Description
We found what looks like a bug, or at least an incomplete OIDC onboarding implementation, in Harbor.
When an OIDC user is onboarded for the first time, Harbor appears to set:
username from the configured OIDC username source
realname to the exact same value as username
This causes incorrect user display names in environments where the technical identifier and the human-
friendly name are intentionally different.
Expected behavior
Harbor should allow the user-facing display name (realname) to be populated from a human-friendly OIDC
claim such as:
name
- or another explicitly configurable claim
while still allowing username to come from a technical identifier claim such as:
userid
preferred_username
In our environment, this separation is necessary and intentional:
- technical identifier: unique and stable
- human-friendly name: readable by users and admins
Actual behavior
Harbor uses the resolved onboarding username for both fields.
As a result, after OIDC onboarding, the Harbor local user record becomes something like:
{
"username": "XXXXXXXXXXX",
"realname": "xxxxxxxxxxxxxxx",
"email": "XXXXXXXXXXXXX"
}
or, depending on configuration, it would become:
- username = userid
- realname = userid
or:
- username = preferred_username
- realname = preferred_username
In all cases, realname is not the actual human-friendly full name.
## Why this is a problem
OIDC commonly carries different kinds of identity attributes:
- technical identifier
- login name
- human-friendly full name
- first name
- last name
Harbor currently seems to collapse at least two of these concerns into one field during onboarding.
That makes OIDC onboarding unsuitable for environments where:
- username must remain technical and stable
- realname must remain human-readable
## Evidence from behavior
Our OIDC token/userinfo contains values like:
{
"name": "XXXXXXXXXXXX",
"preferred_username": "XXXXX",
"userid": "xXXXXXXXXXXX",
"email": "XXXXXXXXXX"
}
But Harbor stores the onboarded user as:
{
"username": "XXXXXXXXXXX",
"realname": "XXXXXXXXXXXX",
"email": "XXXXXXXXXXXXX"
}
## Source code observation
The behavior appears to come from the OIDC onboarding flow.
In src/core/controllers/oidc.go, Harbor creates the user like this:
user := &models.User{
Username: username,
Realname: username,
Email: info.Email,
}
This means realname is always copied from the resolved onboarding username.
Also, in src/pkg/oidc/helper.go, Harbor resolves the OIDC username from:
1. configured oidc_user_claim
2. userinfo username
3. fallback name
So even if the OIDC claim selection is changed, realname still follows username and cannot be
independently mapped.
## Request
Please consider one of these options:
1. Add a dedicated configurable OIDC claim for Harbor realname
2. Default realname to the OIDC name claim when available
3. At minimum, document clearly that Harbor intentionally sets realname = username for OIDC onboarding
## Environment
- Harbor version: v2.15.0
- Auth mode: oidc_auth
- OIDC provider: Keycloak
## Notes
This is not just about cosmetic display.
In real environments, username and realname serve different purposes and should not be conflated.
Description
We found what looks like a bug, or at least an incomplete OIDC onboarding implementation, in Harbor.
When an OIDC user is onboarded for the first time, Harbor appears to set:
usernamefrom the configured OIDC username sourcerealnameto the exact same value asusernameThis causes incorrect user display names in environments where the technical identifier and the human-
friendly name are intentionally different.
Expected behavior
Harbor should allow the user-facing display name (
realname) to be populated from a human-friendly OIDCclaim such as:
namewhile still allowing
usernameto come from a technical identifier claim such as:useridpreferred_usernameIn our environment, this separation is necessary and intentional:
Actual behavior
Harbor uses the resolved onboarding username for both fields.
As a result, after OIDC onboarding, the Harbor local user record becomes something like:
{ "username": "XXXXXXXXXXX", "realname": "xxxxxxxxxxxxxxx", "email": "XXXXXXXXXXXXX" } or, depending on configuration, it would become: - username = userid - realname = userid or: - username = preferred_username - realname = preferred_username In all cases, realname is not the actual human-friendly full name. ## Why this is a problem OIDC commonly carries different kinds of identity attributes: - technical identifier - login name - human-friendly full name - first name - last name Harbor currently seems to collapse at least two of these concerns into one field during onboarding. That makes OIDC onboarding unsuitable for environments where: - username must remain technical and stable - realname must remain human-readable ## Evidence from behavior Our OIDC token/userinfo contains values like: { "name": "XXXXXXXXXXXX", "preferred_username": "XXXXX", "userid": "xXXXXXXXXXXX", "email": "XXXXXXXXXX" } But Harbor stores the onboarded user as: { "username": "XXXXXXXXXXX", "realname": "XXXXXXXXXXXX", "email": "XXXXXXXXXXXXX" } ## Source code observation The behavior appears to come from the OIDC onboarding flow. In src/core/controllers/oidc.go, Harbor creates the user like this: user := &models.User{ Username: username, Realname: username, Email: info.Email, } This means realname is always copied from the resolved onboarding username. Also, in src/pkg/oidc/helper.go, Harbor resolves the OIDC username from: 1. configured oidc_user_claim 2. userinfo username 3. fallback name So even if the OIDC claim selection is changed, realname still follows username and cannot be independently mapped. ## Request Please consider one of these options: 1. Add a dedicated configurable OIDC claim for Harbor realname 2. Default realname to the OIDC name claim when available 3. At minimum, document clearly that Harbor intentionally sets realname = username for OIDC onboarding ## Environment - Harbor version: v2.15.0 - Auth mode: oidc_auth - OIDC provider: Keycloak ## Notes This is not just about cosmetic display. In real environments, username and realname serve different purposes and should not be conflated.