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"
}| Field | Notes |
|---|---|
protocol | saml | oidc |
enabled | master switch for the login endpoints |
SAML: samlEntryPoint, samlIssuer, samlCert | IdP SSO URL, entity ID, signing cert |
OIDC: oidcIssuerUrl, oidcClientId, oidcClientSecret | discovery-based; secret is encrypted at rest |
jitProvisioning | create unknown users on first login (see below) |
defaultRole | org 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:
| Endpoint | Purpose |
|---|---|
GET /sso/:orgId/saml/login | redirect to the IdP |
POST /sso/:orgId/saml/callback | SAML ACS (assertion consumer) |
GET /sso/:orgId/saml/metadata | SP metadata XML for IdP setup |
GET /sso/:orgId/oidc/login | start the OIDC flow (state cookie, 10 min) |
GET /sso/:orgId/oidc/callback | code 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 ifjitProvisioningis 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.