Documentation

SAML SSO & SCIM provisioning

AuditTrail supports enterprise identity integration at the organization level: SAML 2.0 single sign-on so members log in through your IdP, and SCIM 2.0 provisioning so user lifecycle (create / read / deactivate) is driven by your directory. Both are configured per organization and gated by the org RBAC roles (owner > admin > annotator > viewer).

SAML SSO

You register your identity provider's metadata once per org, then your IdP POSTs signed assertions to AuditTrail's Assertion Consumer Service (ACS), which provisions/refreshes the User + OrgMember rows and sets the session cookie.

The config is stored in the saml_configs table and carries the IdP entity ID, SSO URL, X.509 signing certificate, your SP entity ID, a default_role for newly-provisioned members (admin / annotator / viewer), and an enabled flag.

REST surface

MethodPathRolePurpose
POST/api/v1/saml/config/{org_id}ownerCreate or update the org's SAML config
GET/api/v1/saml/config/{org_id}admin+Read the current config
POST/api/v1/saml/acs/{org_slug}signed assertionAssertion Consumer Service

The ACS endpoint takes a standard form POST (SAMLResponse, optional RelayState). AuditTrail validates the assertion signature against the stored IdP cert and audience, upserts the user by email, ensures org membership at the configured default_role, sets the session cookie, and 302-redirects to RelayState (or /overview). An assertion with no email, or one that fails signature/audience checks, is rejected (400/401).

bash
# Point your IdP's ACS URL at:
https://auditrail.yourco.com/api/v1/saml/acs/<your-org-slug>

SCIM 2.0 provisioning

SCIM lets your IdP push user lifecycle into AuditTrail. You mint a SCIM bearer token scoped to one org, configure it in your IdP, and the IdP calls the standard /scim/v2/Users endpoints. Tokens are stored as Argon2 hashes (scim_tokens table) with a 12-char display prefix; the plaintext scim-… secret is shown once at creation.

Token management

MethodPathRolePurpose
POST/api/v1/scim/tokensownerMint a SCIM token for an org (one-time secret)
GET/api/v1/scim/tokens/{org_id}admin+List tokens (prefix only)

Provisioning endpoints

These follow the SCIM 2.0 wire spec and authenticate with Authorization: Bearer scim-… (not a session cookie). They live under /scim/v2, not /api/v1.

MethodPathPurpose
POST/scim/v2/UsersProvision a user (upsert by userName/email, add org membership)
GET/scim/v2/Users/{user_id}Read a provisioned user scoped to the token's org
DELETE/scim/v2/Users/{user_id}Deprovision — removes the user's membership in the token's org

SCIM-provisioned users are created email_verified=True and default to the viewer role within the org. A DELETE removes the OrgMember row (membership) rather than hard-deleting the user account.

Data model

TableHolds
saml_configsOne IdP config per org (entity IDs, SSO URL, cert, default role, enabled)
scim_tokensArgon2-hashed SCIM bearer tokens + prefix, scoped to an org
org_membersMembership + role; written by both the SAML ACS and SCIM provisioning
org_invitesOne-time invite tokens (the manual alternative to SSO/SCIM)

Notes & limits

  • SAML and SCIM are organization-scoped — they presuppose an org exists and the caller is an owner. See the API reference for the org/member/invite endpoints.
  • The ACS sets the session cookie with SameSite=Lax so the IdP-initiated POST navigation lands logged in.
  • SCIM deprovisioning removes org membership; it does not delete trace data, which remains owned by the underlying user account.