Identity providers
An identity provider adds a "Continue with …" button to an issuer's login page, so your users can sign in through an upstream provider instead of (or alongside) a password. auth.is speaks OIDC upstream — it federates to Google, Microsoft Entra ID, Kenni, or any standards-compliant OIDC provider, using the authorization-code flow with PKCE, state, and nonce on every request.
Providers are configured per issuer. Each one is an issuer_provider row with a URL-safe key (used in the /federate/:key and /callback/:key routes), a display name, the upstream clientId / clientSecret, and type-specific config. You manage them from the MCP — this page covers the concepts and a walkthrough; exact tool parameters live in the MCP tool reference.
The four provider types
| Type | Type-specific field | Notes |
|---|---|---|
google | hostedDomains (optional) | The issuer URL is fixed (accounts.google.com). If you set hostedDomains, a login is rejected unless the token's hd claim is on the list — Google Workspace domain restriction. |
entra | tenantId (required) | Microsoft Entra ID. A GUID, or common / organizations / consumers. The issuer URL is derived from the tenant, and a token from a different tenant is rejected. The stable per-user id is oid. |
kenni | issuerUrl (required) | A Kenni issuer, standard OIDC. |
oidc | issuerUrl (required) | Any other compliant OIDC provider. |
For google you never pass an issuer URL (it is preset); for entra the URL comes from the tenant; for kenni/oidc you must supply it. The contract enforces the right field per type, so a wrong combination (an issuerUrl on Google, a missing tenantId on Entra) fails validation before it reaches the server. In production, issuerUrl must be https.
The upstream client secret is write-only. You supply it when adding or updating a provider; no read ever returns it — a listed provider reports only hasSecret: true/false, never the value, not even masked. Public upstreams (which have no secret) simply omit it.
Adding a provider — walkthrough
Ask your AI tool to add a provider with add_identity_provider. A minimal Google example needs the issuer id, a key, a display name, the type, and the upstream clientId / clientSecret you registered at Google:
Add a Google identity provider to my issuer — key
Add Entra with a tenantId, or Kenni/generic OIDC with an issuerUrl, the same way. Every provider is registered with a redirect/callback URL of https://{slug}.auth.is/callback/{key} — register that exact URL at the upstream provider. The change bumps the issuer's configVersion and is live on the login page immediately (see Issuers).
Toggle a provider without deleting it via the enabled flag (on add_identity_provider or update_identity_provider); remove_identity_provider deletes it. list_providers shows the masked config for each.
What happens at login
The one-time PKCE/state/nonce bundle rides the interaction, so an intercepted callback cannot be replayed and state is a pure CSRF nonce. auth.is reads the upstream user from the returned ID token, then decides which local account the login belongs to.
Account linking (verified-email matching)
On callback, auth.is matches the upstream user to a local account by the pair (issuer provider, upstream user id). If that link already exists, the user signs into the same account as last time. If it does not:
- It links to an existing local user only when both the local email and the upstream email are verified.
- Otherwise it creates a fresh, separate user.
An unverified upstream email is never auto-linked to an existing account. This blocks an attacker from claiming someone else's account by signing up at an upstream provider with an unverified copy of their email — a new user is created instead. This is the same rule described in Users & identities; it is why email verification (on both sides) matters.
Restricting providers per client
By default, every provider you enable on the issuer shows on every client's login page. To narrow which providers a specific client offers, use set_client_providers — it sets that client's enabled_providers to a list of provider keys. A client whose list is unset is unrestricted (shows all enabled providers); an empty or specific list shows only what you name. This lets one issuer host, say, an internal app that only offers Entra alongside a public app that offers Google.
Next steps
Users & identities
the linking rule and per-issuer pools in full.
Username & password
the credential federation sits alongside.
Clients
`set_client_providers` and per-client provider restriction.
Issuers
where providers are configured and why edits are instant.
MCP tool reference
exact params for the provider tools.