# How Harbor Handles LDAP, OIDC, and UAA Authentication: A Source Code Analysis

> Explore how Harbor's source code manages LDAP, OIDC, and UAA authentication via pluggable security middleware for unified security contexts and RBAC evaluation.

- Repository: [Harbor/harbor](https://github.com/goharbor/harbor)
- Tags: architecture
- Published: 2026-04-09

---

**Harbor delegates authentication to external identity providers through a pluggable security middleware architecture in [`src/server/middleware/security/security.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/security.go), where provider-specific implementations like `ldap.Auth`, `oidcCli`, and `uaa.Auth` transform credentials into unified security contexts for RBAC evaluation.**

Harbor, the open-source cloud-native registry under the CNCF (goharbor/harbor), implements enterprise authentication via a modular pipeline. When a request enters the system, Harbor’s authentication mode configuration determines which security generator validates credentials against LDAP directories, OIDC providers, or Cloud Foundry UAA servers.

## Authentication Mode Selection and Security Middleware

Every HTTP request passes through the central security middleware defined in [`src/server/middleware/security/security.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/security.go). This middleware reads the active authentication mode from the database configuration and injects it into the request context:

```go
mode, err := config.AuthMode(r.Context())
if err == nil {
    r = r.WithContext(lib.WithAuthMode(r.Context(), mode))
}

```

The middleware maintains a prioritized slice of **security generators** that attempt to create a valid security context. As implemented in the source, the generators slice includes:

```go
generators = []generator{
    &secret{},
    &oidcCli{},      // OIDC token validation
    &v2Token{},
    &idToken{},
    &authProxy{},
    &robot{},
    &basicAuth{},    // LDAP binds via basic auth
    &session{},
    &proxyCacheSecret{},
}

```

Each generator implements `Generate(req *http.Request) security.Context`. When `mode` is set to `ldap_auth`, `oidc_auth`, or `uaa_auth`, the corresponding generator handles credential validation while the others skip processing.

## LDAP Authentication Flow

LDAP authentication is implemented in [`src/core/auth/ldap/ldap.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/ldap/ldap.go). When **basic auth** headers are present and the mode is `ldap_auth`, the flow proceeds as follows:

1. **Session Establishment**: The `ldap.Auth.Authenticate` method loads system LDAP configuration via `ldapCtl.Ctl.Session` (lines 61-70 of [`ldap.go`](https://github.com/goharbor/harbor/blob/main/ldap.go)) and opens a connection to the directory server.
2. **User Lookup**: The implementation calls `SearchUser` to resolve the username to a distinguished name (DN).
3. **Credential Validation**: Harbor binds to the LDAP server using the supplied password to verify credentials.
4. **Group Attachment**: Upon successful bind, `attachLDAPGroup` (lines 98-142) retrieves LDAP group memberships and attaches them to the user model for subsequent RBAC evaluation.

The resulting user object populates `Username`, `Realname`, and `Email` fields, which Harbor stores or updates in its database while maintaining the LDAP linkage for group synchronization.

## OIDC Authentication Flow

OIDC support spans multiple packages: `src/pkg/oidc` for core logic and [`src/server/middleware/security/oidc_cli.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/oidc_cli.go) for request handling.

For incoming requests bearing an `Authorization: Bearer <token>` header, the `oidcCli` generator executes:

1. **Token Extraction**: The `valid` function checks for header presence.
2. **Provider Verification**: `VerifyToken` in [`src/pkg/oidc/helper.go`](https://github.com/goharbor/harbor/blob/main/src/pkg/oidc/helper.go) (lines 220-224) validates the JWT against the configured OIDC provider, verifying audience and issuer claims.
3. **Context Injection**: Upon validation, `InjectGroupsToUser` maps OIDC claims to Harbor groups, and the generator returns an `OIDCContext` implementing the security interface.

The API also exposes a testing endpoint at `POST /c/oidc/onboard` handled by `oidcAPI.PingOIDC` in [`src/server/v2.0/handler/oidc.go`](https://github.com/goharbor/harbor/blob/main/src/server/v2.0/handler/oidc.go), which performs OIDC discovery against the provider to validate configuration before activation.

## UAA Authentication Flow

Cloud Foundry UAA integration resides in [`src/core/auth/uaa/uaa.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/uaa/uaa.go). The implementation registers itself with Harbor’s auth registry on import using `auth.Register(common.UAAAuth, &Auth{})`.

When processing credentials:

1. **Token Exchange**: `Authenticate` exchanges username/password for a UAA access token via `client.PasswordAuth`, then retrieves user details through `client.GetUserInfo` (lines 42-60).
2. **User Onboarding**: If the user does not exist locally, `OnBoardUser` creates a Harbor user record with a default password marked `"From UAA"` (lines 64-77).
3. **Profile Synchronization**: `PostAuthenticate` updates the user profile if UAA attributes have changed (lines 88-102).
4. **Directory Queries**: The `SearchUser` method supports UI lookup functionality by querying the UAA API for user metadata (lines 105-129).

## Security Context and RBAC Integration

Regardless of the provider, successful authentication returns a **security.Context** implementing:

- `GetUsername() string`
- `GetUserID() int`
- `IsSysAdmin() bool`
- `GetRoles() []*rbac.Role`

Harbor’s RBAC engine (`src/common/rbac`) consumes this context to evaluate policies against the user’s roles and LDAP/OIDC/UAA group memberships. The unified interface ensures that authorization logic remains agnostic to the authentication source.

## Summary

- Harbor selects authentication providers via the `AuthMode` configuration, read by security middleware in [`src/server/middleware/security/security.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/security.go).
- **LDAP** authentication uses [`src/core/auth/ldap/ldap.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/ldap/ldap.go) to bind against directories and synchronize groups via `attachLDAPGroup`.
- **OIDC** verification occurs in [`src/pkg/oidc/helper.go`](https://github.com/goharbor/harbor/blob/main/src/pkg/oidc/helper.go) through `VerifyToken`, with request handling by the `oidcCli` generator.
- **UAA** support is implemented in [`src/core/auth/uaa/uaa.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/uaa/uaa.go), handling token exchange, user onboarding, and profile synchronization.
- All providers implement the `auth.AuthenticateHelper` interface and return standardized security contexts for RBAC evaluation.

## Frequently Asked Questions

### How does Harbor determine which authentication provider to use?

Harbor reads the `auth_mode` setting from its configuration database via `config.AuthMode()`. This value (set in the Harbor UI) determines which security generator in [`src/server/middleware/security/security.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/security.go) processes the request. When set to `ldap_auth`, `oidc_auth`, or `uaa_auth`, the corresponding implementation handles credential validation while other generators pass through.

### Can Harbor authenticate users against multiple providers simultaneously?

No. Harbor operates in a single authentication mode at the system level. However, the security middleware maintains a chain of generators (including `secret`, `robot`, and `basicAuth`) to handle different credential types. For example, OIDC tokens and robot accounts can coexist, but all human users must authenticate through the configured primary provider (LDAP, OIDC, or UAA).

### What happens when an LDAP or OIDC user logs into Harbor for the first time?

For LDAP, Harbor creates a local user record during the first successful bind, populating fields from the directory attributes. For OIDC, the `InjectGroupsToUser` function maps claims to Harbor groups during token validation. For UAA, the explicit `OnBoardUser` method in [`src/core/auth/uaa/uaa.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/uaa/uaa.go) creates the user record with a placeholder password and the comment `"From UAA"` to indicate external origin.

### Where does Harbor validate OIDC tokens before allowing API access?

Token validation occurs in [`src/pkg/oidc/helper.go`](https://github.com/goharbor/harbor/blob/main/src/pkg/oidc/helper.go) within the `VerifyToken` function (lines 220-224). The `oidcCli` generator in the security middleware calls this function to validate JWT signatures, issuer claims, and audience against the configured OIDC provider before generating the security context.