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
| Setting | Value |
|---|---|
| Application type | Web, confidential client |
| Grant type | Authorization code |
| Redirect URI | https://<your-host>/auth/callback |
| Scopes | openid, 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.