Skip to main content

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.

The endpoint, tokens, and behavior below 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. Open Configure → Identity provider. Under Authentication, SCIM service shows the service's address, or Not enabled when the chart has not enabled it.

  2. Create a token. Under SCIM tokens, click + Token. Enter a Token name, choose Expire in (30 days or 90 days), and click Add token. Click Copy token, then Done; the value is not shown again.

  3. Give the identity provider the base URL and the token. Under SCIM provisioning, click Copy endpoint beside Endpoint. If it reads Address unknown, the base URL is https://{scim_host}/scim/v2. The base URL has no metalake in it.

  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. Last activity under SCIM provisioning shows when the identity provider last used a token.

  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; see Users.

How provisioning works​

Users, groups, and roles​

A service administrator creates local identities, the identity provider provisions identities over SCIM, and a first sign-in by an unprovisioned user creates a JIT identity; all three land in the server-wide Directory with their origin, and a metalake owner adds them to the metalake and grants 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.

ResourceAttributes
Userid, externalId, userName, active
Groupid, externalId, displayName, members

Gravitino assigns id itself. externalId is the identity provider's own identifier for the record and is optional. A user's displayName is returned as its userName.

Other attributes are ignored when a user is created or replaced with POST or PUT. A user PATCH is different: it accepts only active and externalId, and returns 400 for any other attribute. An identity provider that sends PATCH for profile changes, as Entra does, therefore needs its user mappings cut down to userName, active and, optionally, externalId.

How users are matched​

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's userName and a group's displayName cannot change once provisioned. A request that changes either is rejected with 400, and the identity provider reports the failure on every cycle until the name is changed back.

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.

ResourcePath
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, rotating, and deleting tokens requires the service administrator role.

In the UI, Configure → Identity provider lists the tokens under SCIM tokens with when each was created, when it expires, and when it was last used. + Token creates one, with a lifetime of 30 or 90 days, and the delete control on a token's row removes it.

Over REST, tokens are managed at /api/scim/tokens on the main server:

OperationMethodPathBody
ListGET/api/scim/tokensNone
CreatePOST/api/scim/tokenstokenName, optional expiresInDays
RotatePOST/api/scim/tokens/{token_name}/rotateOptional expiresInDays
DeleteDELETE/api/scim/tokens/{token_name}None

expiresInDays sets the lifetime and must be positive. A token created over REST without it never expires, which is convenient for a first test and a poor choice for production. Rotating without it keeps the token's current expiry.

Rotating issues a new value under the same name, and the old value stops working at once, so the identity provider fails until it has the new one. To replace a token without a gap, overlap two instead: create a second token, give its value to the identity provider, and delete the first once its Last used time stops moving. Several tokens can be valid at once, so the overlap costs nothing. Deleting a token cuts off any identity provider still using it immediately.

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.