Skip to main content

OIDC

Works with any OIDC-compliant provider: Okta, Entra ID, Google Workspace, Auth0, Keycloak, Ping.

Configure

keycloak:
enabled: false
oidc:
issuerUrl: https://acme.okta.com/oauth2/default
clientId: presponsieve

The client secret goes in the application secret, not in values.

Registering the client

SettingValue
Application typeWeb, confidential client
Grant typeAuthorization code
Redirect URIhttps://<your-host>/auth/callback
Scopesopenid, profile, email

Verify the issuer exactly

curl -s https://acme.okta.com/oauth2/default/.well-known/openid-configuration | jq .issuer

That value must match oidc.issuerUrl character for character. A mismatch produces invalid issuer at login with no further detail, and the usual cause is a missing or extra /oauth2/default.

On Entra ID, use the v2.0 issuer: https://login.microsoftonline.com/<TENANT>/v2.0. The v1.0 endpoint emits a different token shape and fails validation.

Multi-replica requires SESSION_SECRET

The login session cookie is signed with SESSION_SECRET. With more than one replica and no shared secret, the SSO callback can land on a pod that cannot validate the cookie the flow started with.

The symptom is an intermittent login loop that looks like an identity provider fault. It is not.

Cookies are Secure

AUTH_COOKIE_SECURE defaults to "1", so the session cookie will not persist over plain HTTP. If you are testing through a port-forward without TLS and login loops, that is why.

Common failures

invalid issuer. The URL does not match the discovery document exactly.

redirect_uri_mismatch. Providers match exactly, including trailing slashes. https://app.acme.com/auth/callback is not https://app.acme.com/auth/callback/.

AADSTS7000215 on Entra. The secret ID was copied instead of the secret value. The value is shown only once, at creation.

Entra client secret expired. They expire, capped at 24 months, and nothing warns you. Put the date in a calendar.

Login loops. Either SESSION_SECRET is unset with multiple replicas, or the load balancer is stripping Set-Cookie, or you are on plain HTTP.