Govern
Documentation

Version Latest

Single sign-on with SAML

Connect Microsoft Entra ID, Okta or another SAML 2.0 identity provider to Neural Inverse Govern, test the connection and activate it, with the settings, certificate rotation and session policy.

SAML connections live in Identity Center. Govern computes every service provider value itself, so you copy values from Govern to your identity provider and import the identity provider's metadata back; you never type an entity ID or certificate by hand.

Before you start

  • You need the sso.connections:* permissions on the organisation. Owner and Admin hold them.
  • In an organisation of several accounts, the Identity Center instance belongs to the management account or a delegated administrator. A member account gets 403 NOT_INSTANCE_ADMINISTRATOR.
  • An organisation can have up to 10 connections.
  • The identity provider must serve https endpoints and sign its assertions.

Set up a connection in the console

Open Identity Center > Connections and choose to add a connection. The setup has six steps, and Govern shows the state of each:

  1. Choose the identity provider. Presets: Microsoft Entra ID, Okta, Google Workspace, Ping Identity, and "Other SAML 2.0 identity provider". The preset fills in the NameID format and attribute names.
  2. Copy the service provider values to your identity provider (below).
  3. Import the identity provider metadata, by URL or as XML.
  4. Preview the attribute and group mapping.
  5. Test sign-in. You sign in through the identity provider yourself; the result shows the subject, email, attributes, groups and the group mappings they would apply.
  6. Activate the tested revision.

A connection's configuration is a revision. Editing an active connection writes a draft while the active revision keeps serving, and a draft can only be activated after a passing test sign-in of that exact revision in the last 24 hours.

Service provider values

ValueForm
Entity ID (identifier, audience URI){origin}/saml/c/{connection_id}
ACS URL (reply URL, single sign-on URL){origin}/saml/c/{connection_id}/acs
Single logout URL{origin}/saml/c/{connection_id}/slo
Metadata URL{origin}/saml/c/{connection_id}/metadata

The metadata at GET /saml/c/{connection_id}/metadata is public and holds the entity ID, the ACS (HTTP-POST), single logout in both bindings, and the active and next signing and encryption certificates.

Microsoft Entra ID

  1. In the Microsoft Entra admin center, open Enterprise applications, create your own application and choose SAML single sign-on.
  2. Enter the identifier (entity ID) and the reply URL (ACS URL), or upload the Govern metadata.
  3. Copy the App Federation Metadata URL from the SAML certificates section and import it in Govern.
  4. Keep the default claims and add a group claim for the groups assigned to the application.

The Entra ID preset reads these claims: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress, .../givenname, .../surname, http://schemas.microsoft.com/identity/claims/displayname and http://schemas.microsoft.com/ws/2008/06/identity/claims/groups. An Entra ID group overage (groups.link) is refused: configure Entra ID to send only the groups assigned to the application.

Okta

  1. In the Okta Admin Console, create a SAML 2.0 app integration and enter the single sign-on URL (ACS URL) and the audience URI (entity ID).
  2. Copy the metadata URL from the Sign On tab and import it in Govern.
  3. Add the attribute statements email, firstName and lastName, and a group attribute statement named groups.

Google Workspace and others

Google Workspace maps the primary email to email, first and last name to firstName and lastName, and "Group membership" to the app attribute groups. For any other identity provider, release the email attribute, and the name and groups attributes if you use them.

Settings

SettingDefaultMeaning
IdpEntityId, IdpSsoUrl, IdpSsoPostUrl, IdpSloUrlfrom the metadataThe identity provider's entity ID, sign-in endpoints and logout endpoint. https only.
IdpCertificatesfrom the metadataOne or two signing certificates. An expired certificate is refused.
MetadataUrlthe imported URLRefreshed daily. Empty for pasted XML.
NameIdFormatthe preset'semail_address, persistent or unspecified. A transient NameID is refused.
AuthnRequestsSignedtrueAuthnRequests are signed with RSA-SHA256.
UseRedirectBindingtrueHTTP-Redirect; false sends an auto-submitted HTTP-POST form.
WantAssertionsSignedalways trueThe assertion must be signed itself; a signed response alone is refused.
WantEncryptedAssertionsfalseWhen on, an unencrypted assertion is refused. RSA-OAEP with AES-GCM or AES-CBC is accepted; RSA 1.5 is refused.
SendLoginHinttrue for Entra ID, Okta and PingSends the email typed at sign-in as the AuthnRequest subject.
AllowIdpInitiated, IdpInitiatedRedirectUrlfalse, emptyIdP-initiated sign-in. When on, the response is verified and replay-checked, then handed off to a normal service-provider-initiated sign-in at the redirect URL.
AttributeMapthe preset'sEmail (required unless the NameID is an email address), GivenName, FamilyName, DisplayName, Groups.

Every response must carry exactly one assertion. Govern checks the issuer, the audience, the destination, a bearer subject confirmation whose recipient is the ACS URL and whose InResponseTo is the pending request, the validity times with two minutes of skew, and an assertion ID replay cache. Documents with a DTD are refused.

Certificates

Each connection gets a signing and an encryption RSA key pair. Certificates are valid for two years, and the private keys are stored only as Govern Vault ciphertext.

  • Rollover. The next certificate is published in the metadata 60 days before the active one expires and becomes active 30 days later.
  • Warnings. Administrators are warned 30, 14, 7 and 1 days before any certificate of a connection expires, the identity provider's included, and when one has expired.
  • Rotate now. RotateServiceProviderCertificate with Stage: PUBLISH_NEXT creates and publishes the next key pair; ACTIVATE_NEXT activates it early once your identity provider trusts it.

Sign-out

Signing out of Govern ends the identity provider session with a signed LogoutRequest to IdpSloUrl. In the other direction, a signed LogoutRequest from the identity provider to /saml/c/{connection_id}/slo (HTTP-Redirect or HTTP-POST) ends the Govern sessions with that SessionIndex and is answered with a signed LogoutResponse. Unsigned or foreign requests are refused with 400 and the reason, and every logout is audited as auth.saml_logout. A deployment without the session-ending component answers 503 slo_unavailable rather than pretending.

Session policy

Per connection, PutConnectionSessionPolicy (sso.sessions:putconnectionsessionpolicy) sets:

FieldRange
MaxSessionMinutes60 to 1440
IdleTimeoutMinutes15 to 480, at most the maximum
ReauthenticationWindowMinutes5 to 60
RequireIdpMfaForAdminOwner and Admin actions need an authentication with the listed amr or acr values
IdpMfaAmrValues, IdpMfaAcrValuesDefault amr value mfa

The change applies at once to the connection's live sessions. A privileged action in a session whose last identity provider authentication is older than the window is refused with reauthentication_required, and the client starts a re-authentication with StartSessionReauthentication.

Refusals

A refused response shows the identity provider failure page and is audited as auth.external_signin with its reason, for example signature_invalid, assertion_unsigned, idp_certificate_expired, audience_mismatch, subject_confirmation_invalid, assertion_expired, encryption_required, encryption_algorithm_refused, decryption_failed, nameid_transient, assertion_replayed or idp_initiated_disabled.

Metadata imports are refused with a reason such as metadata_fetch_failed, metadata_malformed, metadata_expired, metadata_insecure_url, metadata_no_signing_certificate or metadata_certificate_expired. A metadata URL is fetched over https with at most 3 redirects and a 15-second limit, and must resolve to a public address.

API

Identity Center actions are POST /api/v1/svc/sso/<Action> with PascalCase JSON. Every change is audited as sso:<Action> in the transaction of the change; sso:UpdateConnection records the before and after values.

ActionPermission
CreateConnection (Protocol saml, Preset entra_id, okta, google_workspace, ping or generic_saml)sso.connections:createconnection
UpdateConnection (RFC 7396 merge patch over the draft, or DiscardDraft)sso.connections:updateconnection
DescribeConnection, ListConnectionssso.connections:describeconnection, sso.connections:listconnections
GetConnectionSetupsso.connections:getconnectionsetup
ImportIdentityProviderMetadata (MetadataUrl or MetadataXml, at most 1 MiB)sso.connections:importidentityprovidermetadata
GetServiceProviderMetadatasso.connections:getserviceprovidermetadata
StartConnectionTest, GetConnectionTestResultsso.connections:startconnectiontest, sso.connections:getconnectiontestresult
ActivateConnectionRevisionsso.connections:activateconnectionrevision
RotateServiceProviderCertificatesso.connections:rotateserviceprovidercertificate
DisableConnectionsso.connections:disableconnection
DeleteConnectionsso.connections:deleteconnection

DeleteConnection ends every session issued through the connection, and is refused with 409 connection_in_use while a domain points to it in optional or required mode. A test sign-in needs a signed-in administrator; an API key gets 403 TEST_NEEDS_SESSION.

Next

Last reviewed 17 October 2026View as Markdown

Single sign-on with SAML · Docs · Neural Inverse