Skip to Content
EnterpriseSSO & SCIM

SSO & SCIM

Enterprise (sso entitlement). Let your team sign in with the identity provider you already run, and keep the member list in sync automatically. Per-organization single sign-on via SAML 2.0 or OIDC, plus SCIM 2.0 for user and group provisioning from your IdP (Okta, Entra ID, and compatible).

SSO issues the same httpOnly access_token cookie as password login. There is no parallel session mechanism, and everything downstream (RBAC, teams, audit) works identically.

Configuration

Each org has one SSO config, managed by org owners/admins under Settings. Configure OIDC (discovery-based) with just-in-time provisioning:

{ "protocol": "oidc", "enabled": true, "oidcIssuerUrl": "https://login.example.com", "oidcClientId": "almyty", "oidcClientSecret": "…", "jitProvisioning": true, "defaultRole": "member" }
FieldNotes
protocolsaml | oidc
enabledmaster switch for the login endpoints
SAML: samlEntryPoint, samlIssuer, samlCertIdP SSO URL, entity ID, signing cert
OIDC: oidcIssuerUrl, oidcClientId, oidcClientSecretdiscovery-based; secret is encrypted at rest
jitProvisioningcreate unknown users on first login (see below)
defaultRoleorg role for JIT-provisioned users (default member)

Reading the config back masks secrets and includes the computed loginUrl and scimBaseUrl. Set PUBLIC_API_URL on the backend so generated URLs (SAML ACS, metadata, SCIM base, login links) point at your public API origin rather than an internal hostname.

Login endpoints

Per-org, unauthenticated by design:

EndpointPurpose
GET /sso/:orgId/saml/loginredirect to the IdP
POST /sso/:orgId/saml/callbackSAML ACS (assertion consumer)
GET /sso/:orgId/saml/metadataSP metadata XML for IdP setup
GET /sso/:orgId/oidc/loginstart the OIDC flow (state cookie, 10 min)
GET /sso/:orgId/oidc/callbackcode exchange, then cookie + redirect

On a verified assertion the user is resolved by email:

  • Existing active member: logged in.
  • Deactivated member: 401.
  • Unknown user: created with the org’s defaultRole, but only if jitProvisioning is on. Otherwise 401, deferring membership to SCIM or invites.

SCIM provisioning

SCIM lets your IdP drive the member list instead of (or alongside) JIT. Generate a bearer token under Settings (this also enables SCIM for the org), point your IdP at the SCIM base URL shown there, and use the token as the bearer credential.

Supported operations under /scim/v2 (authenticated by the SCIM token, scoped to your org):

  • Users: create, list (filter support is limited to userName eq "…"), read, replace, patch, delete by id
  • Groups: create, list, read, patch, delete by id. Groups map to almyty teams

Deprovisioning (patch active: false or delete) deactivates the user’s org membership, not their account. They lose access to your org, but their user survives if they belong to other orgs. Both Okta and Entra patch payload shapes are handled.