Skip to main content

Directory

Overview​

The Directory is the server-wide list of every user and group the server knows, across all metalakes. Each identity carries an origin recording how it got there.

OriginWhere It Comes From
LocalCreated in the Directory, with a user name and password stored and managed by Datastrato
ProvisionedSent by your identity provider through SCIM. The identity provider owns it, and the Directory does not add, delete, or change its password
JITDiscovered from the token a user presents at sign-in, for users the identity provider has not provisioned. The identity provider owns it

Local accounts sign in with a password and are the recovery path when the identity provider is unavailable.

A user name is unique only within its origin. A local user and a provisioned user with the same name are different identities and are not merged.

Local groups can contain local, provisioned, and JIT users.

Directory and authorize​

The Directory manages identities. Authorize manages what those identities can do in a metalake.

AreaWhat It Covers
Directory, for service administratorsCreate, disable, and delete local users and groups. List every identity with its origin. Show which metalakes each identity belongs to, read-only
Authorize, for metalake ownersAdmit a user to the metalake, grant roles to users and groups, and remove members. Authorize cannot create or delete identities

A user must be admitted to a metalake before a role can be granted there. A group becomes a member of a metalake when a role is granted to it there. See Authorize for roles, grants, and metalake membership.

Deleting a local user removes it from every metalake it belongs to.

Quick start​

Creating a local user takes two things: the basic authenticator enabled on the server, and a service administrator to create the account with.

  1. Enable local sign-in. In my-values.yaml, list basic among the authenticators and set the initial administrator account, then apply the values. The install in Install with Helm already does both.

    my-values.yaml
    gravitino:
    authorization:
    enable: true
    serviceAdmins: admin
    authenticators: "basic"
    admin:
    username: admin
    password: "$ADMIN_PASSWORD"

    Where users also sign in through an identity provider, list both, with the provider first: gravitino.authenticators: "oauth,basic".

  2. Confirm the administrator works. The commands below reuse ADMIN_PASSWORD and the port forward to the server on localhost:8090 from Install with Helm.

    Check the server version as admin
    curl -s -u "admin:$ADMIN_PASSWORD" \
    -H "Accept: application/vnd.gravitino.v1+json" \
    http://localhost:8090/api/version | jq '.version.version'
  3. Create a local user.

    Create a local user
    curl -s -u "admin:$ADMIN_PASSWORD" -X POST \
    -H "Accept: application/vnd.gravitino.v1+json" \
    -H "Content-Type: application/json" \
    -d '{"user":"{user}","password":"{user_password}"}' \
    http://localhost:8090/api/idp/users

The new user can sign in immediately and reaches no metadata until admitted to a metalake, which Granting Access to Metadata covers.

Local users and groups​

A local account holds its user name, password hash, and group membership in the server's own relational metadata store, alongside the rest of its metadata. Clients authenticate with HTTP Basic credentials, and nothing outside the server is required.

Local accounts authenticate callers to the server. They do not issue tokens or assertions that other services can consume, so they are not a single sign-on system and not a replacement for Okta, Microsoft Entra ID, or Keycloak. Use them for proofs of concept, isolated deployments, and as the way in when the identity provider is unavailable. For everything else, see Authentication.

Credentials travel in an HTTP header on every request, so run the server behind HTTPS wherever the network is not fully trusted.

The UI reads gravitino.authenticators from the server and presents a user name and password form when basic is the authenticator in use.

Password and user name rules​

The rules below apply to user creation and password changes alike.

RuleValue
User nameRequired, and must not contain a colon
Password length12 to 64 characters inclusive

Passwords are reset by an administrator rather than changed by the user, so a password change request carries the new password only and no current password.

User operations​

Management endpoints are served under http://{gravitino_host}:8090/api/idp, a path that reflects the plugin's original name rather than the feature's scope. Every request needs Basic authentication as a service administrator, an Accept: application/vnd.gravitino.v1+json header, and, where it carries a body, Content-Type: application/json.

OperationMethodPathBody
Get a userGET/api/idp/users/{user}None
Add a userPOST/api/idp/users{"user":"alice","password":"{password}"}
Reset a passwordPUT/api/idp/users/{user}{"password":"{new_password}"}
Remove a userDELETE/api/idp/users/{user}None

The add-user body uses the field name user rather than name.

Add a local user
curl -s -u "admin:$ADMIN_PASSWORD" -X POST \
-H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-d '{"user":"{user}","password":"{user_password}"}' \
http://localhost:8090/api/idp/users

Group operations​

OperationMethodPathBody
Get a groupGET/api/idp/groups/{group}None
Add a groupPOST/api/idp/groups{"group":"engineering"}
Remove a groupDELETE/api/idp/groups/{group}?force=trueNone
Change group membershipPUT/api/idp/groups/{group}/users{"usersToAdd":["alice"],"usersToRemove":["carol"]}

The add-group body uses the field name group rather than name. Removing a group that still has members fails unless force=true. A membership change requires at least one of usersToAdd or usersToRemove, and accepts both in a single request.

Change group membership
curl -s -u "admin:$ADMIN_PASSWORD" -X PUT \
-H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-d '{"usersToAdd":["alice","bob"],"usersToRemove":["carol"]}' \
http://localhost:8090/api/idp/groups/engineering/users

Provisioned and JIT users​

Provisioned and JIT identities appear in the Directory on their own, one pushed by your identity provider and the other read from a verified token at sign-in. Both are owned by the identity provider, so add, change, and remove them there rather than in the Directory. See SCIM provisioning for provisioned identities and Authentication for the token claims a JIT user is built from.

Metalake membership is not owned by the identity provider. A provisioned or JIT user arrives with none, so admitting them to a metalake is a step taken here.

Granting access to metadata​

A user can authenticate as soon as the Directory knows them, and reaches metadata only once admitted to a metalake and granted privileges there. The two are separate steps, and the user name must match the name the user signs in as.

Add the user to a metalake
curl -s -u "admin:$ADMIN_PASSWORD" -X POST \
-H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-d '{"name":"{user}"}' \
http://localhost:8090/api/metalakes/{metalake}/users

When gravitino.authorization.enable is set to true, only service administrators can create metalakes. See Privileges for roles, privileges, and ownership, and Manage Metalakes for metalake creation.

Connecting engines​

An engine reaches the server by one of two paths, and each takes its own Basic credentials.

Through the Gravitino connector​

Configure the connector for each engine, then add the credentials below. See Spark Authentication, Flink Authentication, and Trino Authentication for the rest of the connector setup.

Spark connector settings
spark.sql.gravitino.authType=basic
spark.sql.gravitino.basic.username={username}
spark.sql.gravitino.basic.password={password}
Flink connector settings
table.catalog-store.gravitino.gravitino.client.auth.type: basic
table.catalog-store.gravitino.gravitino.client.basic.username: {username}
table.catalog-store.gravitino.gravitino.client.basic.password: {password}
etc/catalog/gravitino.properties
gravitino.client.authType=basic
gravitino.client.basic.username={username}
gravitino.client.basic.password={password}

Trino also needs catalog.management=dynamic in etc/config.properties and a restart before the catalogs appear.

Through the Iceberg REST endpoint​

Engines can connect straight to the Iceberg REST service at http://{gravitino_host}:9001/iceberg/ with no Gravitino connector plugin. See Connect Spark via Iceberg REST, Connect Flink via Iceberg REST, and Connect Trino via Iceberg REST for the rest of the setup.

Spark Iceberg REST settings
spark.sql.catalog.{catalog}.rest.auth.type=basic
spark.sql.catalog.{catalog}.rest.auth.basic.username={username}
spark.sql.catalog.{catalog}.rest.auth.basic.password={password}
Flink Iceberg REST options
'rest.auth.type' = 'basic',
'rest.auth.basic.username' = '{username}',
'rest.auth.basic.password' = '{password}'

Trino has no native Basic mode for Iceberg REST and requires Trino 481 or later, so the header is set directly. Generate the encoded credentials with echo -n '{username}:{password}' | base64.

etc/catalog/{catalog}.properties
connector.name=iceberg
iceberg.catalog.type=rest
iceberg.rest-catalog.uri=http://localhost:9001/iceberg
iceberg.rest-catalog.http-headers=Authorization: Basic {base64_credentials}