Skip to content

The v1 docs follow nauthera-server's main branch and its 0.x releases on the way to 1.0, so fields and APIs can still change.

v1

Existing identity providers

Docs version v1 (main)Nauthera is pre-1.0, in a design-partner programUpdated

Most companies that adopt Nauthera already have an identity provider for their workforce: Entra ID, Okta, Google Workspace, Auth0 or Keycloak. You don't have to replace it. Nauthera can sit between your applications and that provider, as their OpenID Connect issuer, while the existing provider stays where people's accounts, passwords and company second factor live.

Three ways to fit in

PatternUsers sign in withGood for
Federate (broker)The existing provider, through a button on Nauthera's sign-in screenWorkforce applications, when the company directory stays the source of truth
ReplaceA password, passkey and second factor held by NautheraApplications whose users are not in any company directory, such as customers or partners, or a company retiring its provider
BothEither, per clientA customer-facing app that also lets staff in through the company provider

The pattern is chosen per organization and per client, not for the whole deployment. A common shape is one organization for the workforce, federated to Entra ID, and one or more for customers, with their own accounts.

What federating gives you

With Nauthera as the applications' issuer and your provider upstream:

  • Applications are declared next to their code. Each one is an OIDCClient manifest in its own repository, reviewed and delivered by the operator, instead of an app registration someone clicks together in the provider's portal.
  • One upstream registration. Nauthera is registered once at the provider. New applications don't need a new registration there, or a ticket to the team that runs it.
  • Tokens shaped for your APIs. Resource indicators, DPoP-bound access tokens, private_key_jwt and per-client lifetimes, set in the manifest (see Tokens & Sender Constraint).
  • The provider's second factor counts. With trustMfa, a sign-in the provider already verified with MFA is not asked for a second factor again.
  • One audit trail of who signed in to which application, in Nauthera's audit log, beside the provider's own sign-in log.

What it does not give you:

  • No SAML. The upstream provider must speak OpenID Connect, as Entra ID, Okta, Google, Auth0 and Keycloak all do, or be GitHub, which signs in with OAuth 2.0 and its REST API. Every application must speak OpenID Connect too. An LDAP directory or Active Directory connects through an LDAPDirectory instead.
  • No group or role claims from upstream. Nauthera reads the provider's ID token, or GitHub's user API, to find or create the account; it does not copy the provider's groups into Nauthera's tokens. Applications that authorize by group keep reading them from the provider's APIs, or you model them as scopes in Nauthera.
  • No SCIM. Accounts are created in Nauthera on a user's first sign-in, not pushed from the directory. See Leavers and deprovisioning.
  • A public provider. The server fetches the provider's discovery document, token endpoint and keys itself, and refuses loopback and private addresses. A provider reachable only inside your network, such as an internal AD FS, cannot be used.

Setting it up

  1. Register Nauthera at the provider as a web application (a confidential client with the authorization code flow). Put the client secret in a Kubernetes Secret.
  2. Declare the provider with an IdentityProvider resource in the organization, and choose the trust settings below.
  3. Register the redirect URI. Once the resource is Ready, add its status.redirectUri (<organization issuer>/v1/auth/federation/<slug>/callback) at the provider.
  4. Offer it per client. Each OIDCClient lists the provider under spec.identityProviders, with allowSignIn and, for just-in-time accounts, allowSignUp.
apiVersion: nauthera.io/v1alpha1
kind: IdentityProvider
metadata:
  name: entra
  namespace: staff              # a namespace the staff organization admits
spec:
  slug: entra
  displayName: Example Corp account
  providerIssuer: https://login.microsoftonline.com/<tenant-id>/v2.0
  clientId: <application (client) id>
  clientSecretRef:
    name: entra-oidc
  trustEmail: true
  allowedEmailDomains: [example.com]
  trustMfa: true

Use a single-tenant issuer, with your tenant's ID, for Entra ID. The multi-tenant common and organizations endpoints do not have one issuer, and would let accounts of other tenants through.

Choosing the trust settings

SettingTurn it on whenLeave it off when
trustEmailThe provider only issues addresses the company controls, and its email_verified is reliable. Needed to link to accounts that already exist, and for allowedEmailDomains.The provider lets users claim any address, such as a consumer provider used for sign-up.
allowedEmailDomainsOnly company addresses should get in through this provider. Recommended for every workforce provider.The provider is for customers with any address.
trustMfaThe provider enforces MFA itself, through conditional access or a sign-on policy, and reports it in amr (Entra ID, Okta, Auth0) or in acr (set mfaAcrValues).The provider does not enforce MFA, or does not report it. Google sends neither claim, so trustMfa has no effect for it; GitHub refuses it.
spareSecondFactorThe provider's users secure their own accounts, but it reports nothing about how they signed in (Google, GitHub), and its sign-ins should not meet Nauthera's second factor. They stay single-factor.Any application of the organization needs a second factor for these users: the setting overrides the second-factor policy and its rules.

trustMfa moves the second factor out of Nauthera. Turn it on only after checking, in the provider's own policy, that every sign-in that reaches Nauthera passed MFA. A sign-in whose token carries neither claim gets Nauthera's own second factor.

Accounts, linking and sign-up

A sign-in through the provider ends in one Nauthera account:

  • Linked before: the same account as last time, found by the provider's subject.
  • An account with the same address exists: linked, but only with trustEmail, a verified address from the provider, and an address the account has verified too.
  • No account: created, when the client sets allowSignUp and the deployment has auth.registration.enabled.

auth.registration.enabled is server-wide. Turning it on so that first sign-ins through the provider create accounts also opens password sign-up at /register in every organization. If you want accounts created only through the provider, keep registration off and create the accounts ahead of time instead (an administrator creates them with email_verified: true, and the first sign-in through a provider trusted for email links to them), or accept open sign-up and restrict it with allowedEmailDomains, which only applies to the provider.

Applications receive Nauthera's sub, not the provider's. It is the account's id in Nauthera and stays the same however the user signs in.

Leavers and deprovisioning

Without SCIM, disabling someone in the company directory does not reach Nauthera by itself. It stops their next sign-in through the provider, but:

  • their Nauthera sign-in session keeps working until it ends (auth.session.idle_ttl 12h, auth.session.absolute_ttl 24h by default),
  • their refresh tokens keep working, since Nauthera does not ask the provider again on a refresh (issuer.refresh_token_ttl, 720h, renewed on every rotation),
  • access tokens already issued stay valid until they expire (issuer.access_token_ttl, 10m),
  • a password set through the forgot-password link still signs in, where the organization has an email relay, since the password form stays on the sign-in screen.

So a leaver process needs a step in Nauthera: block the account through the admin API. A blocked user can neither sign in nor obtain or renew a token. Blocking ends every session they hold, retires their refresh tokens, tells each application that took part in a session over back-channel logout, and keeps the account and its history for investigation. Signing them out everywhere (DELETE /v1/admin/orgs/{slug}/users/{id}/sessions) ends their sessions and retires their refresh tokens, and keeps the account; deleting the user does the same and then removes the account. Start it from the event your HR or directory system already emits:

curl -s -X POST \
  "https://auth.example.com/v1/admin/orgs/staff/users/$USER_ID/block?reason=Leaver+HR-1234" \
  -H "Authorization: DPoP $TOKEN" -H "DPoP: $PROOF"

Each of these needs an administrator's recent sign-in, so a person runs it rather than the {slug}-admin-m2m client: have the event open a task for an administrator, and keep refresh lifetimes short for the workforce organization's clients (refreshTokenTtlSeconds) so access lapses on its own soon after the upstream account is disabled.

Replacing the provider instead

If the company is retiring its provider, or the users were never in one, Nauthera holds the accounts itself: passwords hashed with argon2id, TOTP and passkeys, recovery codes, invitations and password reset by email. Moving accounts and applications over is covered in Migration. Federating first, then removing the provider once every account has a Nauthera password or passkey, is a way to move without a forced password reset on day one.