# Configure an OIDC provider

Source: https://docs.settlemint.com/docs/developers/sso-oidc/configure-provider
Reference for every auth.oidcProviders field, its environment variable, default, and the claim contract any OIDC identity provider must satisfy for DALP sign-in.



DALP configures OIDC sign-in through the `auth.oidcProviders` list in `config.yml`. The list is provider-neutral — each entry describes one OIDC connection, and any standards-compliant issuer works without provider-specific code. This page is the field-by-field reference; for a concrete walkthrough see [FusionAuth setup](/docs/developers/sso-oidc/fusionauth-setup).

## Configuration shape [#configuration-shape]

```yaml
auth:
  oidcProviders:
    - id: ${OIDC_PROVIDER_ID:-}
      displayName: ${OIDC_PROVIDER_DISPLAY_NAME:-}
      issuer: ${OIDC_PROVIDER_ISSUER:-}
      clientId: ${OIDC_PROVIDER_CLIENT_ID:-}
      clientSecret: ${OIDC_PROVIDER_CLIENT_SECRET:-}
      adminClaim: ${OIDC_PROVIDER_ADMIN_CLAIM:-}
      # scopes: optional; defaults to openid email profile
      # requireIssuerValidation: optional; defaults to true
```

The `${VAR:-default}` syntax reads an environment variable and falls back to the value after `:-` when the variable is unset or empty. This lets a single committed `config.yml` carry safe defaults while deployments inject real values through the environment. See [Deploy OIDC in production](/docs/developers/sso-oidc/deploy-production) for the Helm and secret-handling model.

## Field reference [#field-reference]

| Field                     | Environment variable                      | Type      | Default                        | Sensitive | Purpose                                                                                                              |
| ------------------------- | ----------------------------------------- | --------- | ------------------------------ | --------- | -------------------------------------------------------------------------------------------------------------------- |
| `id`                      | `OIDC_PROVIDER_ID`                        | string    | `""`                           | No        | Stable provider identifier. Used as the sign-in button key and in the callback URL path.                             |
| `displayName`             | `OIDC_PROVIDER_DISPLAY_NAME`              | string    | `""`                           | No        | Label shown on the sign-in button. Falls back to `id` when empty.                                                    |
| `issuer`                  | `OIDC_PROVIDER_ISSUER`                    | URL       | `""`                           | No        | OIDC issuer base URL. Discovery is fetched from `${issuer}/.well-known/openid-configuration`.                        |
| `clientId`                | `OIDC_PROVIDER_CLIENT_ID`                 | string    | `""`                           | No        | OAuth client identifier registered with the provider.                                                                |
| `clientSecret`            | `OIDC_PROVIDER_CLIENT_SECRET`             | string    | `""`                           | **Yes**   | OAuth client secret. Inject from a secret store, never commit a real value.                                          |
| `adminClaim`              | `OIDC_PROVIDER_ADMIN_CLAIM`               | string    | `""`                           | No        | Claim value that grants platform admin. Empty means no one is promoted (deny-by-default).                            |
| `scopes`                  | —                                         | string\[] | `["openid","email","profile"]` | No        | OAuth scopes requested. Omit to use the default; the provider must return the required claims.                       |
| `requireIssuerValidation` | `OIDC_PROVIDER_REQUIRE_ISSUER_VALIDATION` | boolean   | `true`                         | No        | Enforce the RFC 9207 authorization-response `iss` parameter. Set `false` only for providers that don't implement it. |

### Enablement predicate [#enablement-predicate]

A provider entry is only activated when `id`, `issuer`, `clientId`, and `clientSecret` are all non-empty. A partially-filled entry parses without error but is silently dropped — it neither disables local login nor renders a (non-functional) sign-in button. `displayName`, `scopes`, and `adminClaim` do not affect activation.

### Issuer and discovery [#issuer-and-discovery]

DALP builds the discovery URL by appending `/.well-known/openid-configuration` to `issuer`. Set `issuer` to the exact base URL the provider advertises as its issuer identifier, with no trailing slash — a mismatch between the configured issuer and the value inside the ID token fails validation.

### Admin claim resolution [#admin-claim-resolution]

`adminClaim` is matched in priority order against the profile claims:

1. If `adminClaim` is empty, the user is never an admin (deny-by-default).
2. If a `roles` array claim contains the `adminClaim` value, the user is an admin.
3. If a `groups` array claim contains the `adminClaim` value, the user is an admin.
4. If a claim named exactly `adminClaim` is the boolean `true` (or the string `"true"`), the user is an admin.
5. Otherwise the user is a regular member.

<Callout type="warning" title="Deny-by-default protects against guessable claims">
  Leaving `adminClaim` empty is the safe default. Avoid a generic value an IdP
  might already emit for unrelated groups — only a deployment that deliberately
  mints the claim should configure it. Because the role re-derives on every
  login, removing the claim at the IdP demotes the user on their next sign-in.
</Callout>

### Issuer validation and RFC 9207 [#issuer-validation-and-rfc-9207]

`requireIssuerValidation` defaults to `true`, requiring the provider to return the `iss` parameter on the authorization response (RFC 9207, a mixup-attack defense that matters when several IdPs are in play). Providers that do not implement RFC 9207 — FusionAuth among them — omit that parameter, and every callback fails with `issuer_missing` until the flag is set to `false` for that provider. The ID token's `iss` claim is still validated against discovery independently of this flag, so disabling RFC 9207 does not disable issuer checking entirely.

Because the flag accepts environment values, the string `"false"` is parsed as the boolean `false` (not coerced to `true` the way `Boolean("false")` would be). Keep the default `true` and override per provider only where the provider provably lacks RFC 9207 support.

## Claim contract [#claim-contract]

The provider must return these claims for the requested scopes:

* **`name`** — required. Account creation fails with `name_is_missing` if absent. Some providers derive `name` from a full-name field rather than first/last name; confirm yours populates it.
* **`email`** plus an honored verification signal — an explicit `email_verified: false` (or `"false"`) is rejected; an omitted `email_verified` is accepted (claim absent is not the same as unverified).
* **a role or group claim** carrying the `adminClaim` value when the user should be a platform admin.

## Other providers [#other-providers]

Okta, Auth0, Keycloak, and similar issuers use the same fields. The differences are mechanical:

* Set `requireIssuerValidation` according to whether the provider implements RFC 9207 (most modern hosted IdPs do — keep the default `true`).
* Map the admin signal to whatever the provider emits — typically a `groups` or `roles` claim you enable on the application or via a claim-mapping rule.
* Ensure the `profile` scope (or the provider's equivalent) returns a populated `name`.

The [FusionAuth setup](/docs/developers/sso-oidc/fusionauth-setup) page shows the full sequence for a provider that needs extra configuration to satisfy this contract.
