Enterprise SSO & SCIM provisioning
What this gives you
| Without SSO | With SSO and SCIM |
|---|---|
| Users invited by email, one at a time | Access follows your directory |
| Offboarding is a manual checklist item | Deactivating in the IdP deactivates here |
| Roles assigned by hand | Roles derived from IdP groups |
| No central audit of who has access | The IdP is the record |
OIDC login
Verification
The id_token is verified before any claim in it is trusted:
| Check | What it proves |
|---|---|
| RS256 signature | The token came from your IdP, verified against its published JWKS |
| Issuer | It came from the issuer you configured |
| Audience | It was minted for this application |
| Expiry | It is current |
| Nonce | It corresponds to the authorization request we started |
Verification takes the JWKS as an input rather than fetching it internally, which means the security-critical path is fully testable without a live IdP.
Group-to-role mapping
The groups claim is mapped to an application role. Where a user is in several
mapped groups, the highest-priority role wins:
| Role | Priority |
|---|---|
| Owner | 100 |
| Admin | 90 |
| Marketer | 60 |
| Developer | 50 |
| Analyst | 40 |
| Support | 30 |
Highest-wins is the safe direction for a login flow: a user in both analysts
and admins should get admin access rather than being locked out of what their
other group grants. Restrict access by removing the group in your IdP, not by
adding a lower-privileged one.
Just-in-time provisioning
A user who authenticates successfully and maps to a role is provisioned on first login. You do not need to pre-create users, though SCIM lets you if you prefer provisioning to be explicit.
SCIM 2.0
Three endpoints:
| Endpoint | Methods | Purpose |
|---|---|---|
/scim/v2/Users | GET, POST | List and create users |
/scim/v2/Users/{id} | GET, PUT, PATCH, DELETE | Read, replace, patch and deactivate a user |
/scim/v2/Groups | GET, POST, PATCH | Groups and membership |
Authentication
Every SCIM request carries two things:
- A
shopquery parameter naming the tenant - An
Authorization: Bearertoken proving the IdP may provision that tenant
The token is per organisation and compared against a stored hash, so the SCIM surface is scoped to exactly one merchant's directory and cannot read across tenants.
All three routes authenticate through one shared implementation. That is deliberate: a copy-pasted auth check is exactly the code that drifts, and an auth path that differs between copies is the least acceptable place for drift.
curl -X GET \
'https://<your-app-host>/scim/v2/Users?shop=example.myshopify.com' \
-H 'Authorization: Bearer <scim-token>' \
-H 'Accept: application/scim+json'
Deactivation
Setting active: false on a user, or removing them via DELETE, deactivates
their membership. Deactivation preserves the audit history — the record of what
they did does not disappear with their access.
Configuration
SSO and SCIM are configured per organisation:
| Setting | Notes |
|---|---|
| Issuer | Your IdP's issuer URL |
| Client ID / secret | The OIDC client. The secret is encrypted at rest |
| JWKS URI | Where the IdP publishes its signing keys |
| Group mappings | IdP group name to application role |
| SCIM bearer token | Generated here; only the hash is stored, so it is shown once |
Client secrets are encrypted at rest. Rows written before encryption was introduced are tolerated as plaintext and re-encrypted on the next save, so existing integrations are not broken by the change. If you have an older configuration, re-saving it upgrades it.
Audit integrity
Every RBAC audit row is signed with HMAC-SHA256 over its canonical content, keyed by a signing key held by the application and never stored in the tenant database.
A verifier recomputes each row's signature: content edited after the fact, or a row forged by someone with database access but not the key, fails the check.
The signature is deliberately per row rather than a strict hash chain — a chain needs an extra read on the audit hot path and forks under concurrency. Per row detects content tampering and forgery; pair it with the append-only ordering of ids and timestamps to reason about deletions.
Tested identity providers
| Provider | OIDC | SCIM |
|---|---|---|
| Okta | ✓ | ✓ |
| Microsoft Entra ID | ✓ | ✓ |
| Google Workspace | ✓ | ✓ |
Any provider that issues a standards-compliant RS256 id_token with a published
JWKS, and speaks SCIM 2.0, should work.
Plan tier
SSO and SCIM are Enterprise features.
See also
- Authentication & scopes — how the app authenticates to Shopify
- API keys & scopes — credentials for the public API
- Data export & GDPR — user data handling