Govern
Documentation

Version Latest

Domains and SSO enforcement

Verify your company's email domains in Neural Inverse Govern, route sign-ins to your identity provider, make single sign-on required, and keep a break-glass way in.

A verified domain tells Govern that addresses at that domain belong to your company. Each verified domain then has an enforcement mode that decides whether people with those addresses are sent to your identity provider, and whether they may still sign in any other way.

The console pages are Identity Center > Domains and Identity Center > Enforcement. The actions are POST /api/v1/svc/sso/<Action>.

Verify a domain

  1. On Identity Center > Domains, add the domain (CreateDomainClaim, sso.domains:createdomainclaim). The default method is a DNS TXT record and covers the domain's subdomains (IncludeSubdomains). You can instead choose HTTP_FILE, which never covers subdomains.

  2. Publish the record Govern returns:

    _keystone-verify.example.com.  TXT  "keystone-domain-verification=<token>"

    For the file method, serve the value at https://<domain>/.well-known/keystone-domain-verification.

  3. Run the check (VerifyDomainClaim). Two matching lookups at least 60 seconds apart verify the claim; a job runs the second within a minute. While pending, Govern also checks automatically.

Nothing changes for anyone when a claim is verified: every new claim starts with enforcement off.

Rules

  • Up to 50 claims per organisation.
  • A pending claim expires after 14 days without verification.
  • Verified claims are re-checked every 24 hours. A failed lookup moves the claim to failing (still effective) and notifies your administrators; after 7 days of continuous failure the claim lapses and its enforcement stops. Re-verifying within 30 days restores it.
  • RecheckDomainClaim forces a check, at most once per hour.
  • Consumer mail domains, public suffixes, Neural Inverse's own domains, lookalike domains and domains another organisation holds are refused (CONSUMER_DOMAIN, PUBLIC_SUFFIX, RESERVED_DOMAIN, DOMAIN_LOOKALIKE, DOMAIN_ALREADY_CLAIMED). The last answer never says who holds the domain.
  • A company that controls a domain someone else claimed can contest it with ContestDomainClaim.
  • A verified DNS claim can be moved to another account of your organisation with StartDomainTransfer (needs a fresh second factor) and AcceptDomainTransfer.

On a self-hosted installation, DNS checks need a resolver: without NI_AUTH_SSO_DNS_RESOLVER the actions answer 503 identity_center_unavailable.

Enforcement modes

Each verified domain has one mode, set on Identity Center > Enforcement (PutDomainEnforcement, sso.enforcement:putdomainenforcement), pointing at one active connection:

ModeEffect
OFFNothing changes. The company sign-in is not offered.
OPTIONALEmail-first sign-in sends the person to the domain's connection. "Sign in another way" still shows the password step.
REQUIREDNo local sign-in for addresses at the domain, except the root user and break-glass.

A mode routes only to an active connection; a draft or disabled connection never routes. When a subdomain has its own claim, it wins over its parent. The sign-in page gives the same answer for existing and unknown addresses.

Making SSO required

Raising a domain to REQUIRED checks three preconditions:

PreconditionMeaning
ACTIVE_CONNECTIONThe domain points to an active connection.
ADMIN_SSO_SIGN_INSomeone allowed to change enforcement signed in through the connection in the last 7 days.
ROOT_USER_MFAThe root user has a second factor.

It also needs an EffectiveDate 7 to 90 days ahead, unless nobody is affected, in which case it applies at once. Affected people are emailed and see a banner. On the date, Govern checks the preconditions again: if one fails, the change becomes BLOCKED_PRECONDITION, sign-in is unchanged and administrators are alerted. A raise can also wait for a second person's approval (AWAITING_APPROVAL).

When required takes effect, sessions that did not use the connection keep working for the grace period (GracePeriodHours, 0 to 24), then end. Root user sessions and break-glass sessions are kept.

Lowering a mode applies at once and withdraws any pending raise. To point a required domain at another connection, lower it to optional first (LOWER_TO_CHANGE_CONNECTION).

While a domain requires SSO, POST /api/v1/auth/login, passkey sign-in and device approvals answer 403 {"code": "sso_required", "domain", "connection_id"} for its addresses, and the hosted sign-in shows an "SSO required" page. If the policy cannot be checked, the answer is 503 identity_center_unavailable.

Break-glass

Break-glass keeps a way in when your identity provider is down. It exists only while a domain of the organisation requires SSO, at /oauth2/break-glass, and only for the console:

  • Who. The root user and up to two emergency administrators. An emergency administrator is a person of the management account with Owner or Admin and an authenticator app or passkey, designated with PutEmergencyAdmins (a fresh second factor is required) and active only after confirming the emailed link within 7 days.
  • How. Email and password, then a TOTP code or passkey, then a written reason of 20 to 500 characters.
  • What they get. A console session of at most one hour with no refresh token. The person signs in again afterwards.
  • Records. Every sign-in and every refused attempt is audited as sso:BreakGlassSignIn with the reason and alerts the administrators and the other emergency administrators. ListEmergencyAdmins shows the last 100 attempts.

A designation is suspended automatically when the person loses their second factor or role.

People with existing accounts

ListDomainUsers lists the logins at a claimed domain, computed on demand. PutDomainUserAction invites one into an account (INVITE), asks them to link to the connection at their next sign-in (REQUIRE_SSO), or leaves them separate (LEAVE_SEPARATE). People see their own status on their profile (GetMyDomainStatus).

Permissions

ActionPermission
CreateDomainClaim, VerifyDomainClaim, RecheckDomainClaim, DeleteDomainClaimsso.domains:createdomainclaim, ...:verifydomainclaim, ...:recheckdomainclaim, ...:deletedomainclaim
ListDomainClaims, DescribeDomainClaimsso.domains:listdomainclaims, sso.domains:describedomainclaim
ContestDomainClaim, StartDomainTransfer, AcceptDomainTransfer, CancelDomainTransfer, ListDomainTransferssso.domains:<action in lower case>
PutDomainEnforcement, GetDomainEnforcementsso.enforcement:putdomainenforcement, sso.enforcement:getdomainenforcement
PutEmergencyAdmins, ListEmergencyAdminssso.enforcement:putemergencyadmins, sso.enforcement:listemergencyadmins
ListDomainUsers, PutDomainUserActionsso.domainusers:listdomainusers, sso.domainusers:putdomainuseraction
ConfirmEmergencyAdmin, GetMyDomainStatusSigned in, for oneself

Owner and Admin hold the sso.* permissions. Every change, and every refused raise, designation or user action, is audited.

Last reviewed 17 October 2026View as Markdown

Domains and SSO enforcement · Docs · Neural Inverse