Features

Markdown

SSO / OIDC

Externa supports optional OIDC/SSO alongside Fortify password and passkey login. Configure a single standards-compliant identity provider (Keycloak, Azure AD OIDC, Google Workspace OIDC, …) in Project settings.

Related

Project settings form: Project settings. Local auth stack: Passkeys · Account settings. Env / APP_URL: Environment variables. Pre-ship gates: Security checklist.

What ships in v1

ConcernBehavior
ProtocolOpenID Connect authorization code via issuer discovery (/.well-known/openid-configuration)
Packagelaravel/socialite + in-app generic OIDC driver
Login UXOptional secondary button on /login when OIDC is fully configured
LinkingMatch IdP sub first; else link by verified email to an existing active user and store oidc_sub
JITOff by default. When on, create users from verified email; honor allowed_domains + default_user_role
SecretsClient secret stored encrypted; edit payloads expose oidc_client_secret_configured only
Local authPassword + passkey paths stay available

Out of scope (v1)

SAML, SCIM, multi-IdP, claim→role matrices, IdP-initiated SSO, treating OIDC as an MFA substitute, forcing SSO-only (disabling password/passkey).

Setup

  1. In the IdP, create a confidential OIDC client.
  2. Set redirect URI to {APP_URL}/auth/oidc/callback (same class of footgun as passkeys / APP_URL).
  3. In Externa Settings → Project → SSO / OIDC:
    • Enable OIDC
    • Issuer URL (base; discovery is appended)
    • Client ID + client secret
    • Optional button label
    • Optional JIT provisioning
  4. Ensure target users already exist (JIT off) or turn JIT on and configure allowed domains / default role.
RouteNameNotes
GET /auth/oidc/redirectauth.oidc.redirectStarts authorize redirect (404 when disabled)
GET /auth/oidc/callbackauth.oidc.callbackToken + userinfo → session login

If the callback fails validation or the IdP rejects the login, you are redirected to /login with the error shown — no redirect loop back to the IdP.

For local QA, a Keycloak profile ships in compose.oidc.yaml (not for production):

docker compose -f compose.yaml -f compose.oidc.yaml --profile oidc up --build

Security notes

  • Never link on unverified email — account takeover risk. Externa requires IdP email_verified.
  • After first successful link, prefer oidc_sub over email.
  • Inactive / soft-deleted users are rejected.
  • OIDC login does not satisfy two_factor_required. SSO-only cohorts still need TOTP/passkey enrollment or the project MFA gate off.
  • Do not trust arbitrary roles / groups claims without an allowlist (not implemented in v1).

Operator checklist

  • [ ] Redirect URI matches production APP_URL
  • [ ] Client secret saved (configured flag true); plaintext never returned on edit
  • [ ] Link-only path verified with an existing user
  • [ ] If JIT on: allowed domains + default role verified; unknown domains rejected
  • [ ] Password and passkey login still work
Previous
Passkeys