Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .vale/styles/config/vocabularies/DependencyTrack/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
(?i)triag(e|ing)
ACLs
APIs
AWS
Active Directory
Aiven
ApacheDS
Expand All @@ -23,6 +24,7 @@ Exploitability
Fedora 389 Directory Server
Flashpoint
GUIDs
GitLab
HDDs
Hackage
IdP
Expand All @@ -49,6 +51,7 @@ Novell
OAuth
OWASP
OneLogin
OpenID Connect
Operandi
PGTune
Packagist
Expand Down Expand Up @@ -144,6 +147,7 @@ sAMAccountName
timestamptz
truststore
truststore
userinfo
walkthrough
walkthroughs
zstd
154 changes: 84 additions & 70 deletions docs/guides/administration/configuring-oidc.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,62 @@
# Configuring OpenID Connect

Dependency-Track supports single sign-on via OpenID Connect (OIDC). When enabled,
users authenticate through an external identity provider (IdP) rather than a
locally managed password.
Dependency-Track supports SSO via [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html)
(OIDC). When enabled, users authenticate through an external identity provider
(IdP) rather than with a locally managed password.

!!! note "Frontend configuration required"
OIDC requires configuration on both the **API server** and the **frontend**.
The API server validates tokens; the frontend initiates the OIDC flow. Both
must be configured with the same issuer and client ID.
The API server validates tokens; the frontend initiates the OIDC flow.
Configure both with the same issuer and client ID.

## Prerequisites

- An OIDC-compatible identity provider with a configured client (app).
- The client must have the Dependency-Track frontend URL registered as a redirect URI.
- The IdP's discovery endpoint (`/.well-known/openid-configuration`) must be
reachable from the API server.
- The IdP's [discovery endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html)
(`/.well-known/openid-configuration`) must be reachable from the API server.

## API server configuration

Configure the following properties on the API server:
Configure all OIDC settings via [app properties](../../reference/configuration/properties.md).
The examples below use property names; see [Application configuration](../../reference/configuration/application.md#environment-variable-mapping)
for how property names map to environment variables.

```ini linenums="1"
DT_OIDC_ENABLED=true
DT_OIDC_ISSUER=https://idp.example.com # IdP's issuer URL
DT_OIDC_CLIENT_ID=dependency-track # Client ID registered with the IdP
DT_OIDC_USERNAME_CLAIM=preferred_username # Claim to use as the DT username
```properties linenums="1"
dt.oidc.enabled=true
dt.oidc.issuer=https://idp.example.com
dt.oidc.client.id=dependency-track
dt.oidc.username.claim=preferred_username
```

### User provisioning

When enabled, user accounts are created automatically on first login:
When enabled, Dependency-Track creates user accounts automatically on first login:

```ini
DT_OIDC_USER_PROVISIONING=true
```properties
dt.oidc.user.provisioning=true
```

### Team synchronisation

When enabled, team membership is driven by a claim in the ID token that contains
a list of group names. Teams must be mapped to those group names in
**Administration → Access Management → Teams**.
When enabled, Dependency-Track derives team membership from a claim that
contains a list of group names. The API server reads the claim from the ID
token first, and falls back to the provider's userinfo response if absent.
Either source works, so configure the claim wherever your IdP makes it
easiest to emit. Map teams to those group names under
**Administration > Access Management > Teams**.

```ini
DT_OIDC_TEAM_SYNCHRONIZATION=true
DT_OIDC_TEAMS_CLAIM=groups # Name of the claim containing group names
```properties
dt.oidc.team.synchronization=true
dt.oidc.teams.claim=groups
```

## Frontend Configuration
## Frontend configuration

The frontend must also be configured to start the OIDC flow. Pass the following
Configure the frontend to start the OIDC flow by passing the following
environment variables to the frontend container:

```yaml linenums="1"
# Docker Compose example
```yaml linenums="1" title="Docker Compose Example"
services:
frontend:
image: ghcr.io/dependencytrack/hyades-frontend:latest
Expand All @@ -61,12 +65,14 @@ services:
OIDC_ISSUER: "https://idp.example.com"
OIDC_CLIENT_ID: "dependency-track"
OIDC_SCOPE: "openid profile email"
OIDC_FLOW: "implicit"
```

!!! note
Some IdPs require the `authorization_code` flow instead of `implicit`. Refer
to your IdP's documentation and adjust `OIDC_FLOW` accordingly.
The frontend defaults to the `code` flow ([authorization code](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
with [PKCE](https://datatracker.ietf.org/doc/html/rfc7636)), which works with
all modern IdPs and is the recommended setting. The [implicit flow](https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth)
(`OIDC_FLOW: "implicit"`) is only needed for IdPs that lack a public-client
configuration compatible with PKCE; [RFC 9700](https://datatracker.ietf.org/doc/html/rfc9700#name-implicit-grant)
no longer recommends it, so prefer `code` whenever the IdP supports it.

---

Expand All @@ -84,10 +90,10 @@ etc.) to match your environment.
4. Under **Mappers**, add a **Group Membership** mapper with token claim name `groups`
if you want team synchronisation.

```ini
DT_OIDC_ISSUER=https://keycloak.example.com/realms/your-realm
DT_OIDC_CLIENT_ID=dependency-track
DT_OIDC_USERNAME_CLAIM=preferred_username
```properties
dt.oidc.issuer=https://keycloak.example.com/realms/your-realm
dt.oidc.client.id=dependency-track
dt.oidc.username.claim=preferred_username
```

### Microsoft Entra ID (Azure AD)
Expand All @@ -98,14 +104,10 @@ DT_OIDC_USERNAME_CLAIM=preferred_username
3. Under **Token configuration**, add an optional claim for `preferred_username` in
the ID token. Add a **Groups** claim if you want team synchronisation.

```ini
DT_OIDC_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0
DT_OIDC_CLIENT_ID=<application-client-id>
DT_OIDC_USERNAME_CLAIM=preferred_username
```

```yaml
OIDC_FLOW: "implicit"
```properties
dt.oidc.issuer=https://login.microsoftonline.com/<tenant-id>/v2.0
dt.oidc.client.id=<application-client-id>
dt.oidc.username.claim=preferred_username
```

!!! note
Expand All @@ -121,67 +123,79 @@ OIDC_FLOW: "implicit"
3. To include groups/roles, add a custom Action or Rule that injects a `groups` claim
into the ID token.

```ini
DT_OIDC_ISSUER=https://your-tenant.auth0.com/
DT_OIDC_CLIENT_ID=<auth0-client-id>
DT_OIDC_USERNAME_CLAIM=nickname
```properties
dt.oidc.issuer=https://your-tenant.auth0.com/
dt.oidc.client.id=<auth0-client-id>
dt.oidc.username.claim=nickname
```

### GitLab

1. In your GitLab instance or gitlab.com, go to **User Settings Applications**.
1. In your GitLab instance or on `gitlab.com`, go to **User Settings > Applications**.
2. Add `https://dtrack.example.com` as a redirect URI.
3. Select the `openid`, `profile`, and `email` scopes.

```ini
DT_OIDC_ISSUER=https://gitlab.com
DT_OIDC_CLIENT_ID=<application-id>
DT_OIDC_USERNAME_CLAIM=nickname
```properties
dt.oidc.issuer=https://gitlab.com
dt.oidc.client.id=<application-id>
dt.oidc.username.claim=nickname
```

For self-hosted GitLab, replace `https://gitlab.com` with your GitLab instance URL.

### Google

1. In the Google Cloud console, create an **OAuth 2.0 Client ID** of type
**Web app**.
1. In the GCP console, create an **OAuth 2.0 Client ID** of type **Web app**.
2. Add `https://dtrack.example.com` to **Authorized JavaScript origins** and
**Authorized redirect URIs**.

```ini
DT_OIDC_ISSUER=https://accounts.google.com
DT_OIDC_CLIENT_ID=<client-id>.apps.googleusercontent.com
DT_OIDC_USERNAME_CLAIM=email
```properties
dt.oidc.issuer=https://accounts.google.com
dt.oidc.client.id=<client-id>.apps.googleusercontent.com
dt.oidc.username.claim=email
```

!!! warning
Google's **Web app** client type requires a `client_secret` at the token
endpoint even with PKCE, and Google does not offer a public client type
for SPAs. The default `code` flow on the frontend cannot complete against
Google without exposing the secret in browser code. As a workaround, set
`OIDC_FLOW: "implicit"` on the frontend; note that
[RFC 9700](https://datatracker.ietf.org/doc/html/rfc9700#name-implicit-grant)
no longer recommends the implicit flow. For a more secure setup, front
Google with an IdP that supports public clients with PKCE (for example
Keycloak or Auth0).

!!! note
Google does not support custom group claims in ID tokens. Team synchronisation
is not available with Google as the IdP unless you use a proxy IdP layer.
Google does not emit custom group claims in either the ID token or the
userinfo response. Team synchronisation is not available with Google as
the IdP unless you use a proxy IdP layer.

### OneLogin

1. In the OneLogin administration portal, create a new **OpenID Connect** app.
2. Set the **Redirect URI** to `https://dtrack.example.com`.
3. Note the **Client ID** and **Issuer URL** from the app's SSO tab.

```ini
DT_OIDC_ISSUER=https://your-subdomain.onelogin.com/oidc/2
DT_OIDC_CLIENT_ID=<client-id>
DT_OIDC_USERNAME_CLAIM=preferred_username
```properties
dt.oidc.issuer=https://your-subdomain.onelogin.com/oidc/2
dt.oidc.client.id=<client-id>
dt.oidc.username.claim=preferred_username
```

### AWS Cognito

1. Create a **User Pool** in the AWS console.
2. Under **App clients**, create a new client with the **implicit grant** flow enabled.
2. Under **App clients**, create a new client with the **authorization code grant**
flow enabled and **Generate a client secret** turned off (public client + PKCE).
3. Add `https://dtrack.example.com` to **Callback URLs**.
4. In the **App client settings**, ensure `openid`, `profile`, and `email` scopes
are selected.
4. In the **App client settings**, select the `openid`, `profile`, and `email`
scopes.

```ini
DT_OIDC_ISSUER=https://cognito-idp.<region>.amazonaws.com/<user-pool-id>
DT_OIDC_CLIENT_ID=<app-client-id>
DT_OIDC_USERNAME_CLAIM=cognito:username
```properties
dt.oidc.issuer=https://cognito-idp.<region>.amazonaws.com/<user-pool-id>
dt.oidc.client.id=<app-client-id>
dt.oidc.username.claim=cognito:username
```

---
Expand Down
2 changes: 2 additions & 0 deletions docs/includes/abbreviations.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
*[DEK]: Data Encryption Key
*[EPSS]: Exploit Prediction Scoring System
*[GHSA]: GitHub Security Advisory
*[IdP]: Identity Provider
*[KEK]: Key Encryption Key
*[LDAP]: Lightweight Directory Access Protocol
*[NVD]: National Vulnerability Database
*[OIDC]: OpenID Connect
*[OSV]: Open Source Vulnerabilities
*[PURL]: Package URL, a standardized format for identifying software packages
*[SBOM]: Software Bill of Materials
Expand Down