SCIM provisioning
Gravitino acts as a SCIM 2.0 service provider. An identity provider pushes users, groups, and group memberships into Gravitino, so access control can be expressed against identities your organization already manages rather than against accounts maintained separately here.
Provisioning is one directional. The identity provider is the source of truth and Gravitino accepts what it sends. Nothing flows back to the identity provider, and changes made directly in Gravitino to a provisioned user are overwritten on the next cycle.
Provisioning is server wide. Users and groups arrive in the server's directory rather than in a metalake, and adding a provisioned user to a metalake is a separate step taken in Gravitino. The identity provider decides who exists; Gravitino decides where they work and what they can do.
This page covers the endpoint, tokens, and behavior that are the same for every identity provider. Setup differs by provider: see Microsoft Entra ID or Okta. Keycloak does not include a SCIM client, so it cannot push users into Gravitino without a third-party plugin.
Quick Start
1. Confirm the SCIM service is running. SCIM runs as an auxiliary service on its own port, 9201
by default, separate from the Gravitino server on 8090. A running service answers an
unauthenticated request for its configuration with 200.
curl https://{scim_host}/scim/v2/ServiceProviderConfig
2. Create a token. Tokens are managed on the main server. The response carries the token value and its expiry, and the value is shown once.
curl -X POST \
-H "Content-Type: application/json" \
-d '{"tokenName": "{token_name}", "expiresInDays": 90}' \
https://{gravitino_host}/api/scim/tokens
3. Give the identity provider the base URL and the token. The base URL has no metalake in it. The UI shows the same URL alongside the other client endpoints.
https://{scim_host}/scim/v2
4. Provision a single user before enabling the scheduled cycle. A successful connection test means the endpoint was reached and the token was accepted. It does not mean the attribute mappings are right.
5. Add the user to a metalake and grant a role. A provisioned user can sign in but reaches nothing until they belong to a metalake and hold a role there, directly or through a group.
How Provisioning Works
Users, Groups, and Roles
Provisioned users and groups appear in the server's directory marked as provisioned, and they cannot be edited or deleted in Gravitino, since the next cycle would restore them. Local users, created in Gravitino with a password, sit alongside them in the same directory.
Group membership changes arrive as PATCH operations adding and removing members. Roles and
privileges are not provisioned. They remain managed in Gravitino, so granting a role to a
provisioned group is what connects directory membership to access.
Nested groups are not flattened. A group whose members are other groups provisions as a group with no users in it unless the identity provider expands the nesting before sending, and most do not.
Supported Attributes
Gravitino stores a small attribute set. Anything else the identity provider sends is accepted and discarded, so extra mappings do no harm but also have no effect.
| Resource | Attributes |
|---|---|
| User | id, externalId, userName, displayName, active |
| Group | id, externalId, displayName, members |
Gravitino assigns id itself. externalId is the identity provider's own identifier for the
record and is optional.
Matching
When the identity provider looks up an existing user, Gravitino matches on externalId if the
request filters on it and otherwise on userName, ignoring case. Entra and Okta both match on
userName by default, so provisioning works without changing their mappings.
A user whose userName changes in the identity provider, for example after a name change, can
arrive as a new user unless externalId carries an identifier that never changes. Mapping
externalId to the identity provider's immutable object ID avoids this.
Deprovisioning
Identity providers signal removal in two different ways, and Gravitino handles both.
A PATCH setting active to false is a soft delete. The user remains in the directory, marked
inactive, and any grants remain recorded. Okta sends this when a user is unassigned from the
application or deactivated in the directory.
A DELETE removes the user outright.
Which one you get depends on the provider and on how deprovisioning is configured there, so confirm the behavior in a test before relying on it. The distinction matters for audit: a soft delete leaves a record of what the user had access to, and a hard delete does not.
The Endpoint
One endpoint serves the whole server, whatever the number of metalakes, so an organization configures one provisioning application in its identity provider.
| Resource | Path |
|---|---|
| Users | /scim/v2/Users |
| Groups | /scim/v2/Groups |
| Service configuration | /scim/v2/ServiceProviderConfig |
Tokens
The SCIM service accepts a static bearer token created on the main server. Creating and deleting tokens requires the service administrator role.
| Operation | Method | Path |
|---|---|---|
| Create | POST | /api/scim/tokens |
| Delete | DELETE | /api/scim/tokens/{token_name} |
expiresInDays sets the lifetime. A token created without it never expires, which is convenient
for a first test and a poor choice for production.
Replace a token by overlapping two. Create a second token, give its value to the identity provider, and delete the first only once provisioning has run on the new one. Each token records when it was last used, which shows whether the identity provider has moved over. Several tokens can be valid at once, so the overlap costs nothing.
Gravitino also supports OAuth on the SCIM endpoints as an alternative to static tokens, for identity providers that can present a bearer token from your authorization server. Static tokens are the path Entra and Okta both use.
Network Requirements
The endpoint must be reachable from the identity provider's cloud over HTTPS on port 443 with a certificate from a publicly trusted authority. Self-signed certificates are rejected. The Helm chart publishes the SCIM service through its own ingress host, separate from the main server.
The provisioning service cannot complete an interactive sign-in, so nothing that issues a login redirect can sit in front of the endpoint. The token is the only authentication layer.
Any load balancer or gateway in the path must pass PATCH and DELETE through, deliver the
Authorization header unmodified, leave the request path unrewritten, and ignore query parameters
it does not recognize.
Service Configuration
Enabling SCIM in the Helm chart sets the server properties it needs. The SCIM service validates
those properties at startup and terminates the server on a mismatch rather than starting without
registering. If the server exits immediately after a configuration change, check that scim
appears in the auxiliary service names, that the principal mapper and custom filter match the
authentication mode you intend to use, and that the groups fields setting is empty.
Troubleshooting
A connection test that succeeds followed by no users appearing usually means nothing is assigned to the application. Both Entra and Okta provision only what is explicitly assigned.
A 401 means the token is wrong, expired, or was deleted without the identity provider being
updated.
A 404 on a path containing /metalakes/ means the identity provider still has a per-metalake
base URL from an earlier configuration. The base URL ends at /scim/v2.
Users provisioning while groups do not is normal on first setup, since group push is configured separately from user assignment in both providers.
Provisioned users who sign in and see nothing have not been added to a metalake, or hold no role in it. Provisioning creates the identity only.