auth.isdocs
Features

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

TypeType-specific fieldNotes
googlehostedDomains (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.
entratenantId (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.
kenniissuerUrl (required)A Kenni issuer, standard OIDC.
oidcissuerUrl (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.

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 google, name "Continue with Google", client id and secret as follows…

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.

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