SCIM 2.0 Provisioning
Tetrapus exposes a full SCIM 2.0 server. Point Okta SCIM, Azure AD provisioning, OneLogin, or any RFC 7644 client at it and Users + Groups appear in Tetrapus automatically. Deactivations propagate. Group-based role assignments propagate. No manual user creation, no SAML JIT — the directory is the source of truth.
What gets provisioned
Endpoint surface
All routes live under /api/v1/scim/v2/.
Discovery endpoints are unauthenticated; resource endpoints require a per-Org bearer token from the
scim_clients table.
| Method | Path | Purpose |
|---|---|---|
| GET | /ServiceProviderConfig | Capability advertisement |
| GET | /ResourceTypes | Available resource types |
| GET | /Schemas | JSON schemas for User and Group |
| GET | /Users?filter=…&startIndex=1&count=100 | List with filter + pagination |
| POST | /Users | Create user |
| GET | /Users/{id} | Read single user |
| PUT | /Users/{id} | Full replace |
| PATCH | /Users/{id} | RFC 7644 patch ops |
| DELETE | /Users/{id} | Deactivate (soft) |
| … | /Groups, /Groups/{id} | Same five verbs as /Users |
Filter parser
Compliant with RFC 7644 §3.4.2. Supported operators:
# Find users with email ending @acme.com who are active
curl -G https://tetrapus.example.com/api/v1/scim/v2/Users \
-H "Authorization: Bearer $SCIM_TOKEN" \
--data-urlencode 'filter=userName ew "@acme.com" and active eq true' scim_clients table
Each Org generates one or more SCIM bearer tokens. The token hash is stored; the plaintext is shown once at creation and must be pasted into the IdP's SCIM provisioning configuration.
CREATE TABLE scim_clients (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL REFERENCES orgs(id),
name TEXT NOT NULL, -- "Okta SCIM"
token_hash TEXT NOT NULL, -- argon2id(token)
token_prefix TEXT NOT NULL, -- first 8 chars for display
enabled INTEGER NOT NULL DEFAULT 1,
last_used_at TEXT,
created_at TEXT NOT NULL,
UNIQUE (org_id, name)
); Example: create a user
curl -X POST https://tetrapus.example.com/api/v1/scim/v2/Users \
-H "Authorization: Bearer $SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "ada.lovelace@acme.com",
"name": { "givenName": "Ada", "familyName": "Lovelace" },
"emails": [{ "value": "ada.lovelace@acme.com", "primary": true }],
"active": true
}' Group-driven role assignment
Tetrapus maps SCIM Groups to internal Groups one-to-one by displayName. Permissions and roles attached to
a Group flow to all members automatically — pushing a user into the
tetrapus-operators group in Okta is enough
to grant the operator role inside Tetrapus on the next sync. No manual mapping table needed.
Status
Shipped: all 13 filter operators above, full /Users + /Groups CRUD, RFC 7644 PATCH op processing
(add / remove / replace), pagination, and ETags. Deferred: SCIM bulk operations
(/Bulk), the SCIM /Me endpoint, and complex multi-valued
attribute filters with sub-attributes (e.g. emails[type eq "work"].value co "@acme" — the
flattened form works).
Related
- SAML 2.0 — pair SCIM provisioning with SAML SSO for the full enterprise stack
- OIDC Consumer
- Principals & Roles — what SCIM-provisioned users land as
- ← Federation overview
Questions?
Reach out for help with integration, deployment, or custom domain codecs.