External identity providers (federation)

Let your users sign in with an account they already have — Google, LinkedIn, or any generic OIDC provider. SemAuth becomes the broker: it talks OIDC to the upstream provider, then issues its own tokens to your apps.

How federation works

When a realm has one or more enabled external IDPs, the login page shows a "Sign in with {name}" button for each. Clicking it sends the user to the upstream provider; on return, SemAuth verifies the provider's ID token, finds or creates the matching local user, and continues your app's original login flow.

sequenceDiagram participant U as User participant SA as SemAuth realm participant IdP as Google / LinkedIn / OIDC U->>SA: Click "Sign in with Google" SA->>IdP: Redirect to provider /authorize (PKCE, state, nonce) U->>IdP: Authenticate & consent IdP->>SA: Redirect to callback with code SA->>IdP: Exchange code at /token IdP->>SA: id_token (verified via provider JWKS) SA->>SA: Match / link / create local user SA->>U: Continue original sign-in (back to your app)

The callback proxy. Providers like Google only accept a fixed redirect URI (no wildcard subdomains). SemAuth registers a single callback on its bare domain — https://semauth.cc/issuers/{issuer_id}/federation/callback — and internally forwards the result to your realm's own host. That bare-domain URL is the one you register at the provider; the admin UI shows it for you.

Adding an external IDP

From a realm, open IDPs (/realms/{issuer_id}/external-idps). The page offers quick-start buttons — + Google, + LinkedIn, + Generic OIDC — which pre-fill the form with that provider's defaults (label, discovery URL, scopes, and the email-verification claim).

At the provider first

Create an OAuth/OIDC client in the provider's console (Google Cloud Console, LinkedIn Developers, etc.). Register the SemAuth callback URL shown in the admin UI as an authorized redirect URI, and copy the provider's Client ID and Client Secret.

The form fields

Label (shown on login page)The button text, e.g. Google.
EnabledCheckbox; on by default. Disabled providers don't appear on the login page.
Client ID (from provider)From the provider's console.
Client SecretFrom the provider's console. Stored encrypted. On edit, leave blank to keep the existing secret.
Discovery URLThe provider's /.well-known/openid-configuration. Click Discover to auto-fill the endpoints below.
Issuer / JWKS URI / Authorization / Token / Userinfo endpointsFilled by Discover, or entered manually. JWKS URI is required (it verifies the provider's ID token).
ScopesDefault openid email profile.
Email Verified Claim (required)The ID-token claim that signals the email is verified (e.g. email_verified). If your provider doesn't emit one, federation isn't supported for it.

All endpoint URLs must be publicly reachable https:// addresses (internal addresses are rejected).

How accounts are matched

On return, SemAuth requires the provider to assert that the user's email is verified (via your configured email-verified claim). Then it matches the user by the stable provider subject identifier:

Admin realms never auto-register through federation — only pre-invited administrators can sign in.

Assurance and federation

Today a federated sign-in is treated as AAL1 (single factor). That means a realm whose policy requires AAL2/AAL3 cannot currently be satisfied by federation alone — those realms should require passkeys. Mapping upstream assurance into SemAuth's acr is planned but not yet wired. See Assurance levels.

Editing & removing

Each provider row has Edit (you can re-run discovery to refresh endpoints) and Delete. Disabling rather than deleting is the safer way to temporarily turn a provider off without losing its configuration.