SettleMint
Deployment

Single sign-on

Configure an external OIDC identity provider for the DALP Console, and understand that a complete entry replaces local sign-in for the whole deployment.

OpenID Connect (OIDC) connects Console sign-in to an external identity provider. One complete provider entry replaces local sign-in for the deployment. Verify the provider, administrator claim, and recovery path before rollout. Wallet verification has separate settings and remains a distinct control.

The Console authenticates through the identity provider or providers you configure under auth.oidcProviders. That value lives on the parent chart, under global.dalpApp.config as the YAML sample below shows, not on the dapp subchart alone. It is shared configuration merged into both the Console's and the API's ConfigMap, which is why the enforcement this page describes runs at the API layer rather than only in the Console's interface. The setting is provider-neutral: any standards-compliant OIDC issuer works, including FusionAuth, Okta, and Auth0.

Default: no external provider

auth.oidcProviders is an empty list by default. With no provider configured, the Console authenticates locally with email and password plus passkeys.

Adding a provider

Each entry in auth.oidcProviders needs an id, a display name, the issuer URL, and a client ID. It also needs a client secret, injected as an environment variable rather than set as a plain value:

global:
  dalpApp:
    config:
      auth:
        oidcProviders:
          - id: "fusionauth"
            displayName: "FusionAuth"
            issuer: "https://auth.example.com"
            clientId: "dalp"
            clientSecret: "${OIDC_PROVIDER_CLIENT_SECRET:-}"
            adminClaim: "dalp-admin"

Everything except clientSecret is plain configuration you set directly in your values file: id, displayName, issuer, clientId, and adminClaim are not secrets. issuer must be an https:// URL, except for a loopback host reserved for local testing; any other http:// issuer fails config decode when the pod boots, not when the chart installs. A render can succeed while the pod later fails config validation. An upgrade that waits for readiness can then time out. clientSecret is the one field you inject from a secret rather than set directly, through the OIDC_PROVIDER_CLIENT_SECRET environment variable or your configured secret-manager equivalent; see Values and secrets for how that injection actually reaches the running pod. Set it from a Kubernetes Secret, never as a literal in your values file or in a plain ConfigMap. An unencrypted values file lands the secret in Helm release history and in etcd, readable by anything with read access to Secrets or ConfigMaps in the namespace. Add more entries to the list to offer more than one provider at sign-in.

An entry only counts as a configured provider once id, issuer, clientId, and clientSecret all have real values. A partially filled entry parses without an error and changes nothing: local sign-in stays active, and no external sign-in option appears. This is deliberate. It stops a values file mid-edit, or a Secret that has not synced yet, from silently taking down local login.

Two further fields are worth setting deliberately rather than leaving at their default:

  • scopes requests the token claims the provider returns. When you omit it, the Console requests openid, email, and profile. Setting scopes replaces that default list; it does not add to it. If you need a role or group claim for adminClaim below, list openid, email, and profile alongside it, or sign-in fails on the missing email claim the platform relies on as the identity anchor.
  • adminClaim names the claim, or the array a claim value must appear in, that grants platform-admin on sign-in. Leave it unset and no OIDC user ever becomes a platform admin through this provider, which is the deny-by-default posture you want until you have scoped who at your identity provider can assign it. Anyone who can set that claim's value for a user at the identity-provider side can make that user a platform admin the next time they sign in, because the role is recomputed on every login. Scope who can assign the claim before you set it, the same way you would scope a platform-admin role grant inside DALP itself.

A complete entry disables local login for the whole deployment

One complete OIDC entry flips a deployment-wide switch, with no per-user exception.Before any OIDC entry is complete, the Console authenticates locally with email, password, and passkey, and a partially filled entry, missing a field or waiting on a secret that has not synced, parses without error and changes nothing. The moment a release rolls out with one entry holding all four required fields, id, issuer, clientId, and clientSecret, the authentication service treats the whole deployment as OIDC-only. It disables the local email and password credential flow at the API layer, rejects passkey sign-in and passkey registration at that same layer, and rejects password change, password reset, email change, and enabling a new login two-factor method as a second, independent check. Two-factor already enrolled stays verifiable and can still be disabled, and wallet-signing two-factor is untouched, because neither is part of that second check. A first OIDC sign-in does not silently adopt a pre-existing local account that shares the same email; it resolves by provider and subject instead. This applies to every user on the deployment the moment the release rolls out: there is no per-user or per-organization exception, and no in-band fallback for an operator who gets locked out. A partial entry never triggers any of this. The only way back is to redeploy with oidcProviders set back to an empty list, which restores local sign-in immediately; no partial fix exists, because enablement is all-or-nothing.One complete OIDC entry flips a deployment-wide switch, with no per-user exception.Before any OIDC entry is complete, the Console authenticates locally with email, password, and passkey, and a partially filled entry, missing a field or waiting on a secret that has not synced, parses without error and changes nothing. The moment a release rolls out with one entry holding all four required fields, id, issuer, clientId, and clientSecret, the authentication service treats the whole deployment as OIDC-only. It disables the local email and password credential flow at the API layer, rejects passkey sign-in and passkey registration at that same layer, and rejects password change, password reset, email change, and enabling a new login two-factor method as a second, independent check. Two-factor already enrolled stays verifiable and can still be disabled, and wallet-signing two-factor is untouched, because neither is part of that second check. A first OIDC sign-in does not silently adopt a pre-existing local account that shares the same email; it resolves by provider and subject instead. This applies to every user on the deployment the moment the release rolls out: there is no per-user or per-organization exception, and no in-band fallback for an operator who gets locked out. A partial entry never triggers any of this. The only way back is to redeploy with oidcProviders set back to an empty list, which restores local sign-in immediately; no partial fix exists, because enablement is all-or-nothing.

What one complete OIDC entry flips at rollout, and the one way back.

Adding one complete OIDC entry does not add external sign-in alongside local sign-in. It replaces local sign-in with external sign-in, for every user on the deployment, the moment the release with that entry rolls out, exactly as the figure above shows. No per-user or per-organization exception exists, and no in-band fallback exists either: an operator who is locked out cannot sign in locally to fix the configuration.

The API enforces these restrictions as well as the Console. Calling a disabled credential flow directly does not bypass the restriction. Two-factor a user already enrolled stays verifiable and can still be turned off, and wallet-signing two-factor is untouched either way, because neither sits inside the second, independent check that blocks password and email changes and new two-factor enrollment.

A first sign-in through OIDC does not silently adopt a pre-existing local account that happens to share the same email address. Returning users resolve by provider and subject instead, so a local account created before SSO was configured stays a separate account rather than merging into the OIDC identity. Plan for this before rollout: a user who needs continuity with their existing local data needs that handled deliberately, not assumed.

Weigh one real trade-off before you roll out a first provider to a production instance. Configuring SSO centralizes authentication at your identity provider. It gives you one place to enforce password policy, revoke access, and audit sign-in. That convenience comes at a cost, because the identity provider also becomes a single point of failure for reaching the Console at all. Stage the rollout in a non-production environment first.

Recovering from a lockout

If a bad OIDC configuration locks every user out, redeploy with oidcProviders set back to an empty list. That restores local email and password sign-in immediately. Restoring local sign-in requires removing every complete provider entry. Alternatively, correct the provider configuration and redeploy to restore external sign-in. Fix the provider configuration in a non-production environment, verify a full sign-in round trip there, then re-enable it in production.

What stays independent

Three things do not follow the all-or-nothing rule above:

  • OIDC-based wallet verification is a separate capability from OIDC sign-in. It uses its own fields, apiKey and applicationId, on the same provider entry, and it does not gate whether local sign-in stays active. A provider can offer wallet verification without offering sign-in, and the reverse.
  • Two-factor a user already enrolled stays fully usable in OIDC-only mode: it can still be verified at login and still be disabled. Only enrolling a new login two-factor method is blocked, alongside password and email changes; wallet-signing two-factor is untouched regardless.
  • A partially configured entry never disables anything. Only an entry with all four required fields set (id, issuer, clientId, clientSecret) counts.

Production rollout checklist

Before you roll a complete OIDC entry into a production instance:

  • Stage and verify the full sign-in round trip in a non-production environment first. Include a user who should land as a platform admin and one who should land as an ordinary member.
  • Confirm clientSecret, and apiKey if you also configure OIDC wallet verification, come from a Kubernetes Secret, never a values literal.
  • Confirm adminClaim is set only if you intend OIDC users to reach platform-admin, and confirm who at your identity provider can assign that claim's value.
  • Register the Console's callback URL with your identity provider before rollout: /api/auth/callback/<provider-id>, using the provider's id field and matching the exact host the Console serves from. A multi-host deployment needs the callback registered for each host.
  • Confirm the redeploy-to-empty-list lockout recovery path above is understood by whoever holds deploy access, before you roll the entry out, not after you need it.

Failure modes

SymptomLikely causeFix
Everyone is locked out after enabling a providerAny complete entry disables local sign-in deployment-wide; this is expected, not a bug.Redeploy with oidcProviders: [], fix the configuration, verify in staging, re-enable.
helm upgrade reports success, but the dapi pod never becomes readyissuer is not an https:// URL (and is not the loopback exception reserved for local testing). Config decode runs at pod boot, not during the Helm install.Set issuer to the identity provider's https:// URL and redeploy.
Sign-in redirects fail with a callback or redirect-URI errorThe callback URL from the production rollout checklist above is not registered with the identity provider, or does not exactly match the host the Console served the request from.Register that callback URL for every host the Console is reachable on.
Sign-in fails or lands with no nameThe token lacks name, or email, or returns email_verified: false. An explicit false is rejected; an absent claim is accepted.Confirm the scopes return a populated name claim and a verified email. Some providers need profile added.
A user signs in through OIDC as an ordinary member when they should land as platform adminThe claim named by adminClaim is missing from that user's identity token, or its shape does not match: a direct boolean, or the claim's value inside a roles or groups array.Confirm the provider actually populates that claim in the token it returns, not only in an internal profile. The fix takes effect on the user's next sign-in.

These sit alongside oidcProviders in the same auth block. restrictOrgCreationToAdmin, membershipLimit, and walletTwoFactor apply the same way whether or not you configure OIDC. enforce2fa does not: it stops applying the moment a complete OIDC entry is active, because the identity provider then owns login authentication and DALP has no local login step left to enforce it against.

SettingPurpose
enforce2faRequires two-factor authentication at local sign-in. Stops applying once a complete OIDC entry is active: an operator who kept enforce2fa: true for its own sake needs an equivalent MFA policy configured at the identity provider before rollout, because DALP can no longer enforce one.
restrictOrgCreationToAdminRestricts who can create a new organization on the instance.
membershipLimitCaps members per organization (default 10,000).
walletTwoFactorConfigures wallet TOTP (RFC 6238): algorithm, digits, period, secret length, issuer string, and used-token expiration.

See also

  • Values and secrets for how a Kubernetes Secret reaches clientSecret and apiKey without touching the values file.
  • Security for the sign-in and two-factor experience from a signed-in user's own account settings.
  • Install the Helm charts for the redeploy command itself.

Frequently asked questions

If I grant a user platform-admin inside DALP, does that survive after they start signing in through OIDC?

Not on its own. adminClaim is re-evaluated on every OIDC login, and an absent or false claim resolves to an ordinary member regardless of any role granted inside DALP beforehand. In an OIDC-only deployment, the identity provider's claim is the source of truth for platform-admin, and an out-of-band grant is overwritten the next time that user signs in.

On this page