Configure SCIM provisioning
Use System for Cross-domain Identity Management (SCIM) to provision directory users, groups, memberships, and deactivation from your identity provider. Stacklok Enterprise implements SCIM 2.0 (RFC 7644) as a service provider.
SCIM records display their source in the console. Update these records in the identity provider. To provision users from Okta without exposing an inbound SCIM endpoint, see Provision Okta users without a public SCIM endpoint.
Declare the issuer first
Add the provider under enterprise-manager.directory.issuers in the platform
chart and create a Secret containing a random bearer token:
kubectl create secret generic directory-scim-token-okta \
-n <NAMESPACE> \
--from-literal=token="$(openssl rand -base64 32)"
Declare the issuer:
enterprise-manager:
directory:
# Absolute base URL for the SCIM endpoints. Set this whenever any issuer is
# configured: some providers reject relative URLs.
scimExternalBaseURL: 'https://<PLATFORM_HOST>'
issuers:
- id: 'okta-prod'
issuer_url: 'https://<TENANT>.okta.com'
audience: 'enterprise-manager'
binding_claim: 'uid'
scim_bearer_token_ref:
namespace: '<NAMESPACE>'
name: 'directory-scim-token-okta'
key: 'token'
| Field | Value |
|---|---|
id | A short name you choose. It becomes a path segment, so keep it URL-safe |
issuer_url | Your provider's OIDC discovery base URL, HTTPS only |
audience | The audience your provider puts in admin tokens |
binding_claim | The claim carrying the stable per-user identifier: uid for Okta, oid for Entra |
scim_bearer_token_ref | The Secret you just created |
provisioning_attribute is optional and defaults to externalId, the SCIM
attribute whose value must match binding_claim. Change it only if your
provider carries that identifier somewhere else.
The endpoint
The issuer's id determines its base URL:
https://<PLATFORM_HOST>/scim/<ISSUER_ID>/v2
Configure the identity provider with this base URL and the bearer token from the
Secret. Standard discovery endpoints and the /Users and /Groups collections
are available beneath the base path.
Give each additional provider its own issuers entry, id, and Secret.
What is supported
| Capability | Supported | Notes |
|---|---|---|
| Users and Groups | Yes | Create, read, replace, delete |
PATCH | Yes | Add, replace, and remove operations |
| Filtering | Yes | Up to 200 results per request |
| Sorting | Yes | sortBy and sortOrder |
| Bulk operations | No | Returns not-implemented; providers fall back to individual requests |
| ETags | No | |
| Password change | No | Credentials stay with your identity provider |
Providers read these capabilities from /ServiceProviderConfig. Large initial
syncs use individual requests because the service does not support SCIM bulk
operations.
How records are matched
The directory matches a user by external identifier and issuer. Use a stable provider identifier so email or name changes update the existing record.
Group membership can reference both users and other groups, so a nested group structure in your provider arrives as subgroups here.
Set it up
- Declare the issuer and create its token Secret, then upgrade the release so the endpoint exists.
- Create the SCIM application, or enable provisioning on your existing single-sign-on application, in your identity provider.
- Set the base URL to
https://<PLATFORM_HOST>/scim/<ISSUER_ID>/v2, using theidyou chose. - Supply the same bearer token you put in the Secret.
- Enable user provisioning and deactivation, then group provisioning.
- Push an initial sync, then confirm in the console under User management that users and groups appear with a SCIM source.
Start with a small test group to validate mappings before a full sync.
Create groups from user attributes
Stacklok Enterprise can create directory groups from attributes stored in SCIM
user profiles, independent of your identity provider. Use this when properties
such as department or costCenter define groups for connector access,
budgets, or reporting.
Configure your identity provider's application profile mapping to include each
attribute as a JSON string. Then add its SCIM attribute path to the existing
issuer's group_variables list:
enterprise-manager:
directory:
scimExternalBaseURL: 'https://<PLATFORM_HOST>'
issuers:
- id: 'okta-prod'
issuer_url: 'https://<TENANT>.okta.com'
audience: 'enterprise-manager'
binding_claim: 'uid'
scim_bearer_token_ref:
namespace: '<NAMESPACE>'
name: 'directory-scim-token-okta'
key: 'token'
group_variables:
- 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department'
- 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:costCenter'
Use the path where the attribute appears in the stored SCIM user document, not
the source profile property's display name. In your identity provider, inspect
the application's profile mapping to find the target SCIM attribute. For Okta,
open the application's Provisioning > To App mappings or inspect its
okta_profile_mapping Terraform resource.
A top-level core attribute uses its attribute name. For example, this SCIM
content uses userName:
{
"userName": "alex@example.com"
}
An extension attribute uses its complete schema URN and attribute name. Standard
organizational properties such as department and costCenter commonly appear
in the enterprise user extension:
{
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
"department": "Marketing"
}
}
The corresponding path is
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department. Paths
are case-sensitive and must match the keys stored in the SCIM user profile.
The variable-group reconciler does not provide a discovery log for attribute
paths. Its skip logs identify only paths that are already present in
group_variables. Use the identity provider's application profile mapping and
schema as the source of truth. For Okta, use the target application's
Provisioning > To App mappings or its okta_profile_mapping Terraform
resource.
logRawOktaAPIData can confirm that Okta returned an expected profile value,
but it does not identify the final stored SCIM path. Raw responses also contain
sensitive identity data, so do not enable this setting solely to discover
attribute paths.
The Enterprise Manager reconciles these groups hourly. For every distinct,
non-empty string value on an active user, it creates a group and maintains its
membership. It trims surrounding whitespace and folds letter case, so
Marketing, marketing, and Marketing produce one group. Missing, null,
empty, non-string, and longer-than-256-byte values produce no membership.
Choose attributes with a bounded set of organizational values. A per-user
attribute such as userName creates one group per user. Administrators can use
derived groups like other directory groups but cannot edit their names or
membership directly.
When a value disappears or you remove a variable from configuration, the group is emptied. Empty groups remain for 90 days before deletion, preserving their stable identity and governance references during the grace period.
After upgrading the platform release, wait for the next hourly reconciliation. Open User management in the console and confirm that each expected value has a group containing the active users with that profile value.
After provisioning
Connector grants and budgets reference the provisioned directory groups. Define a stable naming convention before rollout and update references after renaming a group.
If you use cluster authorization policy, align SCIM directory groups with the OIDC group claims used in policy. See Directory groups and OIDC claim groups.
Next steps
- Users and groups for what these records govern.
- Identity providers to configure upstream OAuth for connectors.
Troubleshooting
Your provider cannot authenticate
Confirm that the token matches the Secret named in scim_bearer_token_ref.
Check the Secret namespace and remove trailing newlines from the value.
The endpoint is not found
Use the issuer id from enterprise-manager.directory.issuers in the path and
confirm that the release includes your updated values.
Groups provisioned by the identity provider are missing
Enable group provisioning after the initial user sync.
Groups from user attributes are missing
Confirm that group_variables is on the correct issuer and that the Enterprise
Manager restarted after the configuration change. Verify that an active user's
SCIM profile contains a non-empty string at the configured, case-sensitive path.
User deactivation does not take effect
Configure the provider to send deactivation.
Duplicate users appear
Check whether the external identifier changed in the provider. Reconcile the records there, then resync.