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:
- 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.
- Copy the service provider values to your identity provider (below).
- Import the identity provider metadata, by URL or as XML.
- Preview the attribute and group mapping.
- 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.
- 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
| Value | Form |
|---|---|
| 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
- In the Microsoft Entra admin center, open Enterprise applications, create your own application and choose SAML single sign-on.
- Enter the identifier (entity ID) and the reply URL (ACS URL), or upload the Govern metadata.
- Copy the App Federation Metadata URL from the SAML certificates section and import it in Govern.
- 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
- 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).
- Copy the metadata URL from the Sign On tab and import it in Govern.
- Add the attribute statements
email,firstNameandlastName, and a group attribute statement namedgroups.
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
| Setting | Default | Meaning |
|---|---|---|
IdpEntityId, IdpSsoUrl, IdpSsoPostUrl, IdpSloUrl | from the metadata | The identity provider's entity ID, sign-in endpoints and logout endpoint. https only. |
IdpCertificates | from the metadata | One or two signing certificates. An expired certificate is refused. |
MetadataUrl | the imported URL | Refreshed daily. Empty for pasted XML. |
NameIdFormat | the preset's | email_address, persistent or unspecified. A transient NameID is refused. |
AuthnRequestsSigned | true | AuthnRequests are signed with RSA-SHA256. |
UseRedirectBinding | true | HTTP-Redirect; false sends an auto-submitted HTTP-POST form. |
WantAssertionsSigned | always true | The assertion must be signed itself; a signed response alone is refused. |
WantEncryptedAssertions | false | When on, an unencrypted assertion is refused. RSA-OAEP with AES-GCM or AES-CBC is accepted; RSA 1.5 is refused. |
SendLoginHint | true for Entra ID, Okta and Ping | Sends the email typed at sign-in as the AuthnRequest subject. |
AllowIdpInitiated, IdpInitiatedRedirectUrl | false, empty | IdP-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. |
AttributeMap | the preset's | Email (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.
RotateServiceProviderCertificatewithStage: PUBLISH_NEXTcreates and publishes the next key pair;ACTIVATE_NEXTactivates 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:
| Field | Range |
|---|---|
MaxSessionMinutes | 60 to 1440 |
IdleTimeoutMinutes | 15 to 480, at most the maximum |
ReauthenticationWindowMinutes | 5 to 60 |
RequireIdpMfaForAdmin | Owner and Admin actions need an authentication with the listed amr or acr values |
IdpMfaAmrValues, IdpMfaAcrValues | Default 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.
| Action | Permission |
|---|---|
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, ListConnections | sso.connections:describeconnection, sso.connections:listconnections |
GetConnectionSetup | sso.connections:getconnectionsetup |
ImportIdentityProviderMetadata (MetadataUrl or MetadataXml, at most 1 MiB) | sso.connections:importidentityprovidermetadata |
GetServiceProviderMetadata | sso.connections:getserviceprovidermetadata |
StartConnectionTest, GetConnectionTestResult | sso.connections:startconnectiontest, sso.connections:getconnectiontestresult |
ActivateConnectionRevision | sso.connections:activateconnectionrevision |
RotateServiceProviderCertificate | sso.connections:rotateserviceprovidercertificate |
DisableConnection | sso.connections:disableconnection |
DeleteConnection | sso.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
- Domains and SSO enforcement to route people to the connection and make it required.
- Permission sets and group mappings to turn identity provider groups into roles.
- Directory sync with SCIM to provision and deprovision people.