Provision users and groups from Microsoft Entra ID
Gravitino acts as a SCIM 2.0 service provider. Microsoft Entra ID acts as the client, pushing users, groups, and memberships into the Gravitino server's directory so that access control can be expressed against identities your organization already manages.
Provisioning is one directional. Entra is the source of truth, and Gravitino accepts what Entra sends. Nothing flows back.
Quick start
-
Create a SCIM token named
entra, in the UI or over REST, as described in SCIM provisioning. -
Note the tenant URL. Entra needs the SCIM base URL, which the UI's Copy endpoint copies under SCIM provisioning, with the compatibility parameter appended. The base URL has no metalake in it.
Tenant URL formathttps://{scim_host}/scim/v2?aadOptscim062020 -
Create a non-gallery application in Entra. Use the option for integrating an application that is not in the Entra gallery, then enable automatic provisioning on it.
-
Supply the tenant URL and token, and test the connection. A successful test means Entra reached the endpoint and authenticated. It does not mean the attribute mappings are correct.
-
Assign a group to the application. Entra provisions only the users and groups assigned to the application. An application with nothing assigned syncs nothing.
-
Run on-demand provisioning for a single user. Confirm the user appears in Gravitino before enabling the scheduled cycle.
-
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.
Prerequisites
Entra requires a Premium license for provisioning to applications that are not in its gallery. Entra ID P1 is sufficient, and it is included in Microsoft 365 E3 and E5, so most organizations already hold it.
The Gravitino SCIM endpoint must be reachable from Microsoft's cloud over HTTPS on port 443, with a certificate from a publicly trusted authority. Entra rejects self-signed certificates. Because the provisioning service cannot complete an interactive sign-in, no proxy that issues a login redirect can sit in front of the endpoint. The SCIM bearer token is the only authentication layer.
Any load balancer in the path must pass PATCH and DELETE through, deliver the Authorization header unmodified, leave the request path unrewritten, and ignore unrecognized query parameters.
SCIM service configuration
The SCIM service runs inside the server pod and listens on port 9201. Setting gravitino.scim.enabled
to true in my-values.yaml sets every server property it needs. Entra reaches the service through
a hostname of its own on the chart's Ingress, set under ingress.scim. It must differ from the UI
hostname, since every path on it routes to the SCIM port.
gravitino:
scim:
enabled: true
ingress:
scim:
enabled: true
host: {scim_host}
tls:
- secretName: {scim_tls_secret}
hosts:
- {scim_host}
Gravitino supports two authentication modes on the SCIM endpoints. Static bearer tokens are the mode Entra uses, since the provisioning service has no way to complete an OAuth flow. OAuth is available for clients that can present a token from your identity provider.
Token management
Tokens are server wide and persist across restarts. Replace a token before it expires by overlapping two: create a second token, give its value to Entra, and delete the first once provisioning has run on the new one. Token operations, in the UI and over REST, are in Tokens.
Configure the application in Entra
Microsoft documents the generic mechanics of setting up provisioning for a non-gallery application. The steps below cover only what is specific to Gravitino.
Use the compatibility parameter. Entra runs two generations of provisioning job. The older one sends requests that do not conform to SCIM 2.0, including PATCH bodies with malformed value structures. Appending aadOptscim062020 to the tenant URL opts the application into the conformant behavior. Gravitino implements the specification as written, so without this parameter you will see PATCH operations fail even though the endpoint is correct.
If you configured an application before adding the parameter and it continues to fail on disabling users, on adding single-valued attributes, or on removing group members, the application is still bound to the older job. Adding the parameter to an existing configuration does not always rebind it. Delete the provisioning configuration and create a new one.
Assign groups rather than individual users. Assigning a group provisions the group object itself along with its members, which exercises both the user and group paths. Assigning users individually leaves group membership untested.
Use on-demand provisioning while you iterate. The scheduled cycle runs on an interval measured in tens of minutes. On-demand provisioning applies to a single user immediately and reports the result of each attribute mapping, which makes it the only practical way to debug a configuration.
Attribute mappings
Entra ships a default mapping set aimed at a generic SCIM target. Gravitino stores only the
attributes below. When a user changes, Entra sends a PATCH for each changed attribute, and
Gravitino rejects a user PATCH on any attribute other than active and externalId, so a mapping
for display name, given name, surname or email fails the next time that attribute changes. Remove
every mapping not listed below.
| Entra attribute | SCIM attribute | Notes |
|---|---|---|
userPrincipalName | userName | Matching attribute, must be marked as such |
Switch([IsSoftDeleted], ...) | active | Controls enable and disable, keep the default expression |
objectId | externalId | Optional, see below |
Set the matching attribute to userName, which is Entra's default. Gravitino also supports matching on externalId.
externalId is optional. Mapping Entra's objectId to it gives you a stable link back to the directory object, which is useful when auditing, but provisioning works without it.
For groups, keep the mappings for displayName and members, and remove the rest.
User names and group names cannot change once provisioned. A changed userPrincipalName or group
displayName is rejected with 400, and Entra reports the failure on every cycle until the name
is changed back.
How deletes behave
Entra distinguishes two operations, and they reach Gravitino differently.
Disabling a user, removing their application assignment, or removing them from an assigned group causes Entra to send a PATCH setting active to false. The record remains in Gravitino's directory, marked inactive, and stops being treated as an active identity.
Deleting a user from the directory causes Entra to send a DELETE after a delay. Entra soft deletes directory objects first and retains them for thirty days, so the DELETE does not arrive immediately after the user disappears from your directory view.
The practical consequence is that most removals you perform in Entra arrive as a deactivation rather than a deletion. Plan any downstream cleanup around active rather than around the presence of the record.
Group provisioning
Gravitino provisions groups as SCIM group resources with their memberships. Membership changes arrive as PATCH operations that add or remove individual members rather than replacing the whole list.
Nested groups are not provisioned. Entra flattens nothing on your behalf, so a group whose members are other groups arrives with those groups as members and their users do not appear. Assign leaf groups.
Filter matching on user userName and group displayName ignores case.
Troubleshooting
The connection test fails with an authentication error. Confirm the token has not expired and that the load balancer is passing the Authorization header through. A proxy that strips or rewrites the header produces the same symptom as a bad token.
The connection test fails with a certificate error. Entra requires a publicly trusted certificate. Certificates that browsers accept because of a local trust store addition will still fail.
Users provision but attributes are empty. The source attributes are unset on the directory objects. Entra sends what it has, and a user with no given name provisions with no given name.
PATCH operations fail while creates succeed. The application is bound to the older provisioning job. Recreate the provisioning configuration with aadOptscim062020 in the tenant URL.
Duplicate records appear on every cycle. The matching attribute is not set to userName. Entra is failing to recognize existing records and creating new ones.
Nothing provisions at all. Confirm that users or groups are assigned to the application. Provisioning scope covers assigned principals only.
Entra records every provisioning attempt with the request it sent and the response it received. The provisioning logs are the fastest way to distinguish a mapping problem from an endpoint problem, and they should be the first place you look before inspecting the Gravitino server logs.