SSO & SCIM setup
Configure SAML 2.0 single sign-on and SCIM 2.0 user provisioning for Okta, Microsoft Entra ID (Azure AD), Google Workspace, and OneLogin.
Pact federates with any SAML 2.0 IdP and supports SCIM 2.0 for automatic user lifecycle management. SAML carries the login. SCIM carries provisioning, deprovisioning, and group membership.
This page is the operator setup guide for the four most common IdPs. Pact is IdP-agnostic — anything that speaks SAML 2.0 (HTTP-POST binding on the ACS, HTTP-Redirect on the AuthnRequest) will work, including AD FS, Ping, JumpCloud, and Authentik.
What you get
- Single sign-on — SAML 2.0 with assertion-signature verification, replay protection, audience restriction, and clock-skew tolerance per SAML Core §4.1.4.
- JIT user provisioning — first login from your IdP creates the Pact user record. No manual seat onboarding.
- SCIM 2.0 user lifecycle — push user creates, updates, deactivations, and group memberships from your IdP. Standard
/scim/v2/Usersand/scim/v2/Groupsendpoints. - Per-domain SSO routing — users entering their work email at
/loginare auto-redirected to the right IdP via a discovery probe. - SP-initiated and IdP-initiated logins — both bindings work; the ACS handler validates
InResponseTocorrectly in both cases. - Single Logout — SP- and IdP-initiated SLO with embedded XML-DSig signature verification (closes the XML signature wrapping attack).
- Full audit log — every SAML and SCIM event lands in the tenant audit log under the
auth.saml.*andauth.scim.*action namespaces.
Where to set it up
Configure SSO in the admin UI — never through environment variables or platform secrets.
- Wizard —
/admin/ssowalks through provider cards for Google Workspace, Microsoft Entra ID, and Okta. Domain claims, the SSO-required toggle, and the auto-join-by-domain switch all live here. - Direct SAML CRUD —
/admin/sso-samllists every IdP the tenant has registered, lets you paste IdP metadata XML or fill in entityID / SSO URL / certificate by hand, and offers a "Test connection" button that opens an SP-initiated login in a new tab. - SCIM token + groups —
/admin/scim-groupsgenerates the SCIM bearer token your IdP pushes into theAuthorization: Bearer …header and shows the inbound provisioning audit feed.
Quick provider setup
Okta (SAML)
- In Pact, open
/admin/sso-saml→ Add IdP → copy the SP metadata URL shown in the dialog. - In Okta admin → Applications → Create App Integration → SAML 2.0.
- App name: "Pact". Logo: download from the Pact brand kit (or skip).
- Single sign on URL: paste the ACS URL from Pact (
https://app.pact.place/v1/sso/saml/acs). - Audience URI (SP Entity ID): paste the SP entity ID from Pact.
- Name ID format:
EmailAddress. Application username:Email. - Attribute statements — add these four:
email→user.emailfirstName→user.firstNamelastName→user.lastNamegroups(Group Attribute Statement, filter "Matches regex:.*") →user.groups
- In Okta → Sign-On tab → View SAML Setup Instructions → copy the Identity Provider metadata URL.
- Back in Pact → paste it into the IdP metadata URL field, save, then click Test connection.
Microsoft Entra ID / Azure AD (SAML)
- In Pact, open
/admin/sso-samland copy the SP metadata URL. - In the Entra portal → Enterprise applications → New application → Create your own application → Integrate any other application you don't find in the gallery.
- Select Single sign-on → SAML.
- Basic SAML Configuration — paste the SP Identifier (entity ID), Reply URL (ACS), and Sign on URL from Pact.
- Attributes & Claims:
email→user.mailfirstName→user.givennamelastName→user.surnamegroups→ group claim with "All groups" or "Groups assigned to the application"
- Download the Federation Metadata XML and paste it into Pact's IdP metadata field, save, then Test connection.
- Assign the app to the users / groups that should be able to sign in.
Google Workspace (OIDC via wizard)
Google Workspace uses OIDC in the Pact wizard — no XML required.
- In Pact, open
/admin/sso→ Google Workspace card → Set up. - In Google Cloud Console → APIs & Services → Credentials → OAuth client ID → Web application.
- Authorized redirect URI: paste the redirect URI shown in Pact (
https://app.pact.place/v1/sso/oauth/callback). - Copy the Client ID and Client secret into the Pact wizard.
- Add the email domains you want to auto-route (e.g.
@yourcompany.com). - Click Save then Test connection.
OneLogin (SAML)
- In Pact, open
/admin/sso-samland copy the SP metadata URL + ACS URL. - OneLogin admin → Applications → Add App → search for SAML Custom Connector (Advanced).
- Configuration tab:
- Audience (EntityID) → paste Pact SP entityID.
- Recipient → paste Pact ACS URL.
- ACS (Consumer) URL Validator →
^https:\/\/app\.pact\.place\/v1\/sso\/saml\/acs$. - ACS (Consumer) URL → paste Pact ACS URL.
- SAML signature element → Assertion.
- SAML nameID format → Email.
- Parameters tab — map
email,firstName,lastName,groupsto the matching OneLogin user attributes. - SSO tab → copy the Issuer URL and X.509 Certificate.
- In Pact → fill IdP Entity ID, SSO URL, X.509 cert by hand, save, then Test connection.
SCIM provisioning
SCIM is independent of SAML — you can run SAML without SCIM, or both. SCIM means your IdP can push new hires, role changes, and offboardings into Pact without an admin doing it by hand.
- In Pact →
/admin/scim-groups→ Generate SCIM token. Copy it once — Pact never shows it again. - In your IdP's app → Provisioning → Configure API integration (or equivalent).
- SCIM Connector base URL:
https://app.pact.place/scim/v2 - Authorization:
Bearer <token>— bearer token mode. - Map the standard SCIM attributes (
userName,name.givenName,name.familyName,emails[0].value,active). Pact reads them from the standard SCIM 2.0 user schema (RFC 7643). - Map groups → Pact roles via the group sync section in
/admin/scim-groups. Each Pact role can be claimed by one or more IdP group names.
The supported SCIM operations:
| Operation | Endpoint | What it does in Pact |
|---|---|---|
| Create user | POST /scim/v2/Users | Creates the local user, JIT-provisions tenant membership. |
| Update user | PATCH /scim/v2/Users/:id | Updates name/email; active=false deactivates. |
| Soft-delete | PATCH active=false | User can no longer log in. Data is retained. |
| Hard-delete | DELETE /scim/v2/Users/:id | Removes the user row. SOC 2 reviewers typically prefer soft-delete. |
| Create group | POST /scim/v2/Groups | Creates a SCIM group; map to a Pact role for RBAC. |
| Update group membership | PATCH /scim/v2/Groups/:id | Adds / removes members; role mapping fires on the next member login. |
| List + filter | GET /scim/v2/Users?filter=... | Standard SCIM filter syntax (RFC 7644). |
Force-SSO and per-domain auto-join
Once Test connection succeeds, flip Require SSO for all users in /admin/sso. After that:
- Email/password login is blocked for any account in your tenant.
- The login page detects the SAML domain on email blur and renders Sign in with SSO above the password field.
- Per-domain auto-join can be toggled on so any new user from your verified domain auto-joins your tenant on first SAML login (still JIT — they have to exist in your IdP).
Domain claims require DNS TXT verification — paste the TXT record value Pact gives you into your DNS, click Verify, and Pact polls until it sees the record. Until verified, domain-based routing won't redirect new emails.
What gets audited
Every SAML and SCIM event lands in the tenant audit log under auth.saml.* and auth.scim.*. Examples:
auth.saml.login.start— SP-initiated login was kicked off.auth.saml.acs.success— assertion validated, session issued.auth.saml.acs.failure— assertion rejected; thereasonfield carries the taxonomy (signature_invalid,replay,audience_mismatch,notbefore,notafter,subject_missing, ...).auth.saml.slo.success/.failure— Single Logout.auth.saml.idp.created/.updated/.deleted— admin actions on the IdP config row.auth.scim.user.created/.updated/.deactivated/.deleted.auth.scim.group.created/.updated/.membership_changed.
Filter the audit log by action prefix in /admin/security/audit-log.
Troubleshooting
"Test connection" opens a tab but the IdP rejects the AuthnRequest. Your SP metadata in the IdP is stale. Re-download Pact's SP metadata XML and re-paste it. The entityID changes if you change your custom domain.
Login fails with signature_invalid in the audit log. The IdP signing cert in Pact doesn't match what the IdP is using. Re-fetch the IdP metadata URL or paste the current X.509 cert.
Login fails with audience_mismatch. The IdP is sending the wrong <Audience> element. It must equal Pact's SP entityID exactly.
SCIM returns 401 on every request. The bearer token rolled or was revoked. Re-generate in /admin/scim-groups and update your IdP.
Users land in Pact but with no role. No SCIM group → Pact role mapping fired. Add a mapping in /admin/scim-groups or grant a default role in /admin/iam.
My IdP isn't listed in the wizard. Use the Add IdP dialog in /admin/sso-saml — the manual fields work for any SAML 2.0 IdP. The wizard is a convenience layer; everything is generic SAML underneath.