# Harbor Enterprise Identity Provider Integration: LDAP/AD and OIDC Authentication Explained

> Learn how Harbor enterprise identity provider integration works with LDAP/AD and OIDC. Securely authenticate users and manage access with Harbor's unified framework.

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

---

**Harbor integrates with enterprise identity providers by using a configurable `auth_mode` setting that switches between LDAP/Active Directory and OpenID Connect (OIDC) plugins, both of which authenticate users, synchronize group memberships, and map administrative privileges through a unified authentication framework.**

Harbor, the open-source cloud-native registry, provides robust enterprise identity provider integration through its pluggable authentication architecture. By setting the `auth_mode` configuration to either `ldap_auth` or `oidc_auth`, administrators can connect Harbor to existing corporate directories or identity platforms like Active Directory, Keycloak, or Dex. This guide examines the implementation details in the goharbor/harbor source code to show exactly how these integrations function.

## Authentication Mode Configuration

Harbor's identity provider integration centers on the `auth_mode` configuration key defined in [`src/common/const.go`](https://github.com/goharbor/harbor/blob/main/src/common/const.go). The system supports three primary modes: `db_auth` for local database authentication, `ldap_auth` for LDAP/Active Directory, and `oidc_auth` for OpenID Connect providers.

The configuration is accessed at runtime through `config.AuthMode` in [`src/lib/config/userconfig.go`](https://github.com/goharbor/harbor/blob/main/src/lib/config/userconfig.go):

```go
// src/lib/config/userconfig.go
func AuthMode(ctx context.Context) (string, error) {
    mgr := DefaultMgr()
    err := mgr.Load(ctx)
    if err != nil {
        log.Errorf("failed to load config, error %v", err)
        return "db_auth", err
    }
    return mgr.Get(ctx, common.AUTHMode).GetString(), nil
}

```

Harbor's UI, API handlers, and CLI tools invoke this function to determine which authentication plugin to execute for each request.

## LDAP and Active Directory Integration

When `auth_mode` is set to `ldap_auth`, Harbor delegates authentication to an external LDAP or Active Directory server. This implementation resides in [`src/core/auth/ldap/ldap.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/ldap/ldap.go) and supports user authentication, group synchronization, and administrative role mapping.

### Configuration Schema

LDAP settings are retrieved via `LDAPConf` in [`src/lib/config/userconfig.go`](https://github.com/goharbor/harbor/blob/main/src/lib/config/userconfig.go), which loads parameters including server URL, bind credentials, base DN, and group search filters:

```go
// src/lib/config/userconfig.go
func LDAPConf(ctx context.Context) (*cfgModels.LdapConf, error) {
    // ...
    return &cfgModels.LdapConf{
        URL:               mgr.Get(ctx, common.LDAPURL).GetString(),
        SearchDn:          mgr.Get(ctx, common.LDAPSearchDN).GetString(),
        SearchPassword:    mgr.Get(ctx, common.LDAPSearchPwd).GetString(),
        BaseDn:            mgr.Get(ctx, common.LDAPBaseDN).GetString(),
        UID:               mgr.Get(ctx, common.LDAPUID).GetString(),
        Filter:            mgr.Get(ctx, common.LDAPFilter).GetString(),
        Scope:             mgr.Get(ctx, common.LDAPScope).GetInt(),
        ConnectionTimeout: mgr.Get(ctx, common.LDAPTimeout).GetInt(),
        VerifyCert:        mgr.Get(ctx, common.LDAPVerifyCert).GetBool(),
    }, nil
}

```

### Authentication Flow and Session Management

The LDAP authentication process follows these steps implemented in [`src/core/auth/ldap/ldap.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/ldap/ldap.go) and [`src/controller/ldap/controller.go`](https://github.com/goharbor/harbor/blob/main/src/controller/ldap/controller.go):

1. **Session Establishment**: The `Session` method in [`src/controller/ldap/controller.go`](https://github.com/goharbor/harbor/blob/main/src/controller/ldap/controller.go) creates a connection to the configured LDAP server:

```go
// src/controller/ldap/controller.go
func (c *controller) Session(ctx context.Context) (*ldap.Session, error) {
    cfg, groupCfg, err := c.ldapConfigs(ctx)
    // ...
    return ldap.NewSession(*cfg, *groupCfg), nil
}

```

2. **User Search and Bind**: The system searches for the user's DN using the configured `UID` attribute (typically `sAMAccountName` for Active Directory or `uid` for OpenLDAP), then performs an LDAP bind with the supplied password.

3. **Group Attachment**: Upon successful authentication, `attachLDAPGroup` maps LDAP group memberships to Harbor's internal group system:

```go
// src/core/auth/ldap/ldap.go
func (l *Auth) attachLDAPGroup(ctx context.Context, ldapUsers []model.User, u *models.User, sess *ldap.Session) {
    // read LDAP group config, map group DN → Harbor group
    // if group matches the admin DN, set u.AdminRoleInAuth = true
    // populate user‑group relationships via ugCtl.Ctl.Populate
}

```

### Administrative Privileges via LDAP Groups

Harbor grants system administrator privileges when a user's LDAP group DN matches the `ldap_group_admin_dn` configuration value. During the `attachLDAPGroup` execution, the system sets `u.AdminRoleInAuth = true` if the user belongs to the designated administrative group, allowing centralized privilege management through your directory service.

## OIDC Integration

For modern identity platforms, Harbor's `oidc_auth` mode implements the OpenID Connect Authorization Code flow. This integration is handled by [`src/core/auth/oidc/oidc.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/oidc/oidc.go) and the security middleware in [`src/server/middleware/security/idtoken.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/idtoken.go).

### OIDC Configuration Parameters

Settings are loaded via `OIDCSetting` in [`src/lib/config/userconfig.go`](https://github.com/goharbor/harbor/blob/main/src/lib/config/userconfig.go):

```go
// src/lib/config/userconfig.go
func OIDCSetting(ctx context.Context) (*cfgModels.OIDCSetting, error) {
    // ...
    return &cfgModels.OIDCSetting{
        Name:               mgr.Get(ctx, common.OIDCName).GetString(),
        Endpoint:           mgr.Get(ctx, common.OIDCEndpoint).GetString(),
        VerifyCert:         mgr.Get(ctx, common.OIDCVerifyCert).GetBool(),
        AutoOnboard:        mgr.Get(ctx, common.OIDCAutoOnboard).GetBool(),
        ClientID:           mgr.Get(ctx, common.OIDCCLientID).GetString(),
        ClientSecret:       mgr.Get(ctx, common.OIDCClientSecret).GetString(),
        GroupsClaim:        mgr.Get(ctx, common.OIDCGroupsClaim).GetString(),
        GroupFilter:        mgr.Get(ctx, common.OIDCGroupFilter).GetString(),
        AdminGroup:         mgr.Get(ctx, common.OIDCAdminGroup).GetString(),
        // ...
    }, nil
}

```

### Authorization Code Flow Implementation

The OIDC login process routes through handlers defined in [`src/server/route.go`](https://github.com/goharbor/harbor/blob/main/src/server/route.go):

1. **Initiation**: Users click "Log in with OIDC" which redirects to `common.OIDCLoginPath` handled by [`src/server/handler/oidc.go`](https://github.com/goharbor/harbor/blob/main/src/server/handler/oidc.go).

2. **Token Exchange**: After the IdP redirects to `common.OIDCCallbackPath`, Harbor exchanges the authorization code for ID and access tokens.

3. **Token Validation**: The [`src/server/middleware/security/idtoken.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/idtoken.go) middleware validates the ID token signature, issuer, and audience, then extracts user claims:

```go
// src/server/middleware/security/idtoken.go
setting, err := config.OIDCSetting(ctx)
// validate signature, issuer, audience etc.
// extract sub, iss, user claim, groups claim

```

### Group Synchronization and Auto-Onboarding

When `AutoOnboard` is enabled, Harbor automatically creates local user records from validated ID tokens. Group memberships are derived from the claim specified by `GroupsClaim` (commonly `groups`), filtered by the `GroupFilter` regular expression. Members of the group named in `OIDCAdminGroup` receive Harbor system administrator privileges.

The user response includes `WithOIDCInfo: auth == common.OIDCAuth && id > 1` as implemented in [`src/server/v2.0/handler/user.go`](https://github.com/goharbor/harbor/blob/main/src/server/v2.0/handler/user.go) (line 231), enabling the UI to display OIDC-specific elements like CLI secret management.

## Plugin Registration and Unified Framework

Both authentication methods register themselves in their respective `init()` functions, enabling Harbor's dispatcher to route authentication requests appropriately:

```go
// src/core/auth/ldap/ldap.go
func init() { auth.Register(common.LDAPAuth, &Auth{}) }

// src/core/auth/oidc/oidc.go
func init() { auth.Register(common.OIDCAuth, &Auth{}) }

```

This architecture allows Harbor to switch between identity providers without code changes, simply by updating the `auth_mode` configuration and restarting the service.

## Configuration Examples

### Enabling LDAP Authentication

Configure LDAP integration in [`harbor.yml`](https://github.com/goharbor/harbor/blob/main/harbor.yml) or through the UI:

```yaml
auth_mode: ldap_auth
ldap_url: ldap://ldap.mycompany.com:389
ldap_search_dn: cn=admin,dc=mycompany,dc=com
ldap_search_password: <redacted>
ldap_base_dn: dc=mycompany,dc=com
ldap_uid: sAMAccountName
ldap_filter: (objectClass=person)
ldap_scope: 2
ldap_group_base_dn: ou=Groups,dc=mycompany,dc=com
ldap_group_admin_dn: cn=harbor_admin,ou=Groups,dc=mycompany,dc=com

```

### Enabling OIDC Authentication

```yaml
auth_mode: oidc_auth
oidc_name: Keycloak
oidc_endpoint: https://keycloak.mycompany.com/realms/production
oidc_client_id: harbor
oidc_client_secret: <redacted>
oidc_auto_onboard: true
oidc_groups_claim: groups
oidc_group_filter: ^harbor-.*$
oidc_admin_group: harbor-admins
oidc_scope: openid,profile,email,offline_access

```

### CLI Authentication with OIDC

```bash

# Obtain OIDC token from your provider

export OIDC_TOKEN=$(your-oidc-helper --get-token)

# Login using token as password

harbor login myharbor.example.com --username <email> --password $OIDC_TOKEN

```

### Creating LDAP Group Mappings via API

```bash
curl -u admin:adminpw -X POST "https://myharbor/api/v2.0/usergroups" \
  -H "Content-Type: application/json" \
  -d '{
        "group_name": "developers",
        "ldap_group_dn": "cn=dev_team,ou=Groups,dc=mycompany,dc=com",
        "group_type": 1
      }'

```

Note that `group_type: 1` corresponds to `LDAPGroupType` defined in [`src/common/const.go`](https://github.com/goharbor/harbor/blob/main/src/common/const.go).

## Summary

- Harbor uses the `auth_mode` configuration key to switch between database, **LDAP/AD**, and **OIDC** authentication methods loaded from [`src/lib/config/userconfig.go`](https://github.com/goharbor/harbor/blob/main/src/lib/config/userconfig.go).
- **LDAP integration** binds to external directories via [`src/core/auth/ldap/ldap.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/ldap/ldap.go), supporting user search, password validation, and group membership synchronization through `attachLDAPGroup`.
- **OIDC integration** implements the Authorization Code flow in [`src/server/handler/oidc.go`](https://github.com/goharbor/harbor/blob/main/src/server/handler/oidc.go), validates tokens in [`src/server/middleware/security/idtoken.go`](https://github.com/goharbor/harbor/blob/main/src/server/middleware/security/idtoken.go), and supports auto-onboarding and group claim mapping.
- Both methods register via `auth.Register()` using constants from [`src/common/const.go`](https://github.com/goharbor/harbor/blob/main/src/common/const.go), allowing seamless switching between identity providers.
- Administrative privileges can be assigned through **LDAP group DN matching** (`ldap_group_admin_dn`) or **OIDC group membership** (`oidc_admin_group`).

## Frequently Asked Questions

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

Harbor reads the `auth_mode` configuration from the database via `config.AuthMode()` in [`src/lib/config/userconfig.go`](https://github.com/goharbor/harbor/blob/main/src/lib/config/userconfig.go). Valid values include `db_auth` for local authentication, `ldap_auth` for LDAP/Active Directory, and `oidc_auth` for OpenID Connect. The authentication dispatcher uses this value to select the appropriate registered plugin.

### Can Harbor automatically create users from OIDC tokens?

Yes. When `oidc_auto_onboard` is set to `true` in the configuration, Harbor automatically creates local user records upon first successful OIDC authentication. This behavior is handled by the OIDC authentication plugin in [`src/core/auth/oidc/oidc.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/oidc/oidc.go), which implements the `OnBoardGroup` interface to synchronize user data without manual intervention.

### How does group membership work with LDAP integration?

During LDAP authentication, the `attachLDAPGroup` method in [`src/core/auth/ldap/ldap.go`](https://github.com/goharbor/harbor/blob/main/src/core/auth/ldap/ldap.go) queries the LDAP directory for group memberships using the configured `ldap_group_base_dn` and filter settings. It then maps these LDAP groups to Harbor's internal group system. If a user's group DN matches `ldap_group_admin_dn`, Harbor grants system administrator privileges by setting `AdminRoleInAuth = true`.

### What OIDC claims does Harbor use for group mapping?

Harbor extracts group information from the ID token claim specified by the `oidc_groups_claim` configuration parameter (commonly set to `groups`). The optional `oidc_group_filter` applies a regular expression to filter which groups are imported into Harbor. Members of the group specified in `oidc_admin_group` automatically receive system administrator access according to the logic in [`src/controller/user/controller.go`](https://github.com/goharbor/harbor/blob/main/src/controller/user/controller.go).