Federate to your IdP

TL;DR — Instead of AuthPlane managing passwords, delegate the “who is this user” question to Google, Okta, Entra ID, Auth0, or any OIDC provider. Users click “Sign in with <provider>”, authenticate with their existing credentials, and AuthPlane auto-provisions or links a local account. The OAuth token issuance still happens in AuthPlane — federation only changes login. One upstream provider at a time (use Dex if you need multiple).

When you need this

  • Your org already uses Google Workspace, Okta, Entra ID, or Auth0 for SSO.
  • You don’t want to manage passwords in AuthPlane.
  • You need to enforce your IdP’s MFA, conditional access, session policies.
  • You’re deploying AuthPlane for a team that already has corporate accounts.

If none of these apply, skip federation — local login works out of the box.

How the flow works

User clicks "Sign in with <Provider>"
  → AuthPlane redirects to your IdP's /authorize
  → User authenticates with your IdP (MFA, SSO, whatever)
  → Your IdP redirects to AuthPlane's /oidc/callback with an auth code
  → AuthPlane exchanges the code for ID token claims (email, name)
  → AuthPlane creates or links the local user account
  → OAuth flow continues normally — /authorize → consent → /token

The key point: OIDC federation handles who the user is. Consent, tokens, scopes, and everything downstream work exactly the same as with local passwords.

Prerequisites (any provider)

Before touching AuthPlane’s config, you need at your IdP:

  1. A registered OAuth/OIDC application.
  2. The IdP’s issuer URL.
  3. Client ID + client secret from the IdP.
  4. Redirect URI: https://<your-authserver>/oidc/callback — registered at your IdP.

Setup by provider

Google Workspace

  1. Go to Google Cloud Console → APIs & Services → Credentials.
  2. Create an OAuth 2.0 Client ID (type: Web application).
  3. Add https://auth.example.com/oidc/callback as an authorized redirect URI.
  4. Configure AuthPlane:
oidc:
  enabled: true
  issuer: https://accounts.google.com
  client_id: "your-google-client-id.apps.googleusercontent.com"
  client_secret: "your-google-client-secret"
  display_name: Google
  redirect_uri: https://auth.example.com/oidc/callback
  scopes: [openid, email, profile]
  include_groups_scope: false     # Google doesn't support groups scope

Okta

  1. Okta Admin Console → Applications → Create App Integration.
  2. Choose OIDC → Web Application.
  3. Set sign-in redirect URI to https://auth.example.com/oidc/callback.
  4. Configure AuthPlane:
oidc:
  enabled: true
  issuer: https://your-org.okta.com
  client_id: "okta-client-id"
  client_secret: "okta-client-secret"
  display_name: Okta
  redirect_uri: https://auth.example.com/oidc/callback
  scopes: [openid, email, profile]
  include_groups_scope: true      # Okta supports groups

Microsoft Entra ID (Azure AD)

  1. Azure Portal → App registrations → New registration.
  2. Set redirect URI to https://auth.example.com/oidc/callback (Web platform).
  3. Create a client secret under Certificates & secrets.
  4. Configure AuthPlane (replace {tenant-id} with your Azure AD tenant ID, or common for multi-tenant):
oidc:
  enabled: true
  issuer: https://login.microsoftonline.com/{tenant-id}/v2.0
  client_id: "entra-client-id"
  client_secret: "entra-client-secret"
  display_name: Microsoft
  redirect_uri: https://auth.example.com/oidc/callback
  scopes: [openid, email, profile]

Auth0

  1. Auth0 Dashboard → Applications → Create Application → Regular Web Application.
  2. Under Settings → Allowed Callback URLs, add https://auth.example.com/oidc/callback.
  3. Configure AuthPlane:
oidc:
  enabled: true
  issuer: https://your-tenant.auth0.com/
  client_id: "auth0-client-id"
  client_secret: "auth0-client-secret"
  display_name: Auth0
  redirect_uri: https://auth.example.com/oidc/callback
  scopes: [openid, email, profile]

Dex — for multiple upstream providers

AuthPlane supports one upstream OIDC provider directly. For multiple providers (e.g., Google + Okta simultaneously), use Dex as an OIDC broker and point AuthPlane at Dex:

oidc:
  enabled: true
  issuer: https://dex.example.com
  client_id: "dex-client-id"
  client_secret: "dex-client-secret"
  display_name: SSO
  redirect_uri: https://auth.example.com/oidc/callback
  connector_id: github     # optional: pre-select a Dex connector

Without connector_id, Dex shows its own login page listing every configured connector. With it, users skip straight to that upstream.

Env-var equivalents

Every OIDC field can also be set via env vars — useful for CI/CD and Kubernetes Secrets:

AUTHPLANE_OIDC_ENABLED=true
AUTHPLANE_OIDC_ISSUER=https://accounts.google.com
AUTHPLANE_OIDC_CLIENT_ID=your-client-id
AUTHPLANE_OIDC_CLIENT_SECRET=your-client-secret
AUTHPLANE_OIDC_DISPLAY_NAME=Google
AUTHPLANE_OIDC_REDIRECT_URI=https://auth.example.com/oidc/callback
AUTHPLANE_OIDC_SCOPES=openid,email,profile

Full mapping in Reference: Configuration → OIDC.

Kubernetes (Helm) — don’t hard-code secrets

Don’t put client_secret in values.yaml. Two patterns:

Env-var injection from a Secret:

config:
  oidc:
    enabled: true
    client_secret_ref: AUTHPLANE_OIDC_CLIENT_SECRET

extraEnv:
  - name: AUTHPLANE_OIDC_CLIENT_SECRET
    valueFrom:
      secretKeyRef:
        name: oidc-credentials
        key: client-secret

Full config as sealed Secret (GitOps friendly):

existingConfigSecret: my-sealed-config

Both patterns work with Sealed Secrets, External Secrets Operator, or SOPS. See Operate: Kubernetes → Secrets management for OIDC.

What happens to user accounts

New user via OIDC — AuthPlane auto-provisions a local user using the ID token’s email and name claims.

Existing user with matching email — AuthPlane links the OIDC identity to the existing local account. The user can then log in via either method (password OR OIDC) if show_local_login: true.

Force everyone through the IdP — set oidc.show_local_login: false to hide the password form entirely. Existing local users can still be managed via the Admin API but can’t log in with passwords via the UI.

Validation and boot rules

AuthPlane enforces on boot when oidc.enabled: true:

  • oidc.issuer is required.
  • oidc.client_id is required.
  • Exactly one of oidc.client_secret or oidc.client_secret_ref (env-var name) must be set.
  • oidc.redirect_uri is required.
  • oidc.issuer and oidc.redirect_uri must use HTTPS in production (i.e., when server.issuer is not localhost).

The oidc.scopes list is not boot-checked; you should still include openid (and typically email and profile) so account provisioning has data to fill in — but a misconfigured list won’t fail boot, it’ll fail at first login.

Boot fails with a structured error if any of the required keys is missing.

Limitations

  • Single upstream provider at a time. Use Dex as a broker for multi-IdP setups.
  • email claim required in the ID token. Without it, AuthPlane can’t create or match accounts.
  • No group/role sync yet — the include_groups_scope option pulls groups into the ID token when your IdP supports it, but AuthPlane doesn’t use them for authorization decisions. Consent grants and per-tool scope enforcement remain the authorization model.

Troubleshooting

ProblemLikely causeFix
”OIDC authentication failed”Wrong client_secret or unreachable IdPCheck AuthPlane logs for oidc errors; verify curl <issuer>/.well-known/openid-configuration from the AuthPlane host works
User not created after successful loginIdP didn’t return an email claimVerify email is in oidc.scopes AND that your IdP app is configured to return email claims
Redirect loop between AuthPlane and IdPoidc.redirect_uri misconfiguredMust point to https://<your-authserver>/oidc/callback — NOT your IdP’s callback
redirect_uri mismatch error from IdPURI at IdP ≠ oidc.redirect_uriCheck exact match including trailing slash and port
OIDC button doesn’t appear on login pageoidc.enabled: false or config not loadedCheck config; if using env vars verify AUTHPLANE_OIDC_ENABLED=true in the running container
Users authenticate but end up on a blank pageSession secret unstable (regenerated on restart)Set AUTHPLANE_SESSION_SECRET to a stable 32+ byte value