Skip to main content

Iceberg federation

Federation places an existing Iceberg REST catalog behind Gravitino without moving any metadata. You register the remote catalog as a Gravitino Iceberg catalog with catalog-backend set to rest, and Gravitino proxies namespace and table operations to it. The remote catalog remains the system of record for its own tables.

The remote catalog also remains the authority on access. Gravitino forwards the caller's identity, and the remote catalog decides what that caller may see, vends the credentials for reading the data, and records the access in its own audit trail. Gravitino contributes a single endpoint, a shared namespace across every catalog in the metalake, and the tags and policies it holds at the metadata layer.

Any implementation of the Iceberg REST specification can be federated, including another Gravitino server or a vendor catalog service.

An engine loads a table from the Iceberg REST service; for the federated catalog, Gravitino forwards the caller's own token to the remote Iceberg REST catalog, which authorizes the caller and returns the metadata and credentials; the engine then reads the remote catalog's data in object storage directly

Quick start​

Federating a catalog is a single catalog creation call against a running Gravitino server. The example below federates a remote catalog named sales that lives on another Iceberg REST server.

  1. Create the catalog. Point uri at the remote Iceberg REST endpoint, and set warehouse to the name of the catalog you want on that endpoint.

    Create a federated catalog
    curl -sS -X POST "https://{gravitino_host}/api/metalakes/{metalake}/catalogs" \
    -H "Accept: application/vnd.gravitino.v1+json" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    -d '{
    "name": "federated_sales",
    "type": "RELATIONAL",
    "provider": "lakehouse-iceberg",
    "properties": {
    "catalog-backend": "rest",
    "uri": "https://{remote_host}/iceberg",
    "warehouse": "sales",
    "table-metadata-cache-impl": ""
    }
    }'
  2. Read it back through Gravitino. The federated catalog behaves like any other catalog in the metalake.

    List schemas in the federated catalog
    curl -sS "https://{gravitino_host}/api/metalakes/{metalake}/catalogs/federated_sales/schemas" \
    -H "Accept: application/vnd.gravitino.v1+json" \
    -H "Authorization: Bearer $TOKEN"

    The token must also be accepted by the remote catalog, because Gravitino forwards it; see Pass the caller's identity.

  3. Reach it from an engine. Any Iceberg REST client can read the same catalog through the Gravitino Iceberg REST service by using the catalog name as the prefix. See Iceberg REST catalog service for the service configuration.

Identify the remote catalog​

Two properties describe where the federated metadata lives, and they are easy to confuse.

PropertyMeaningRequired
uriThe base URI of the remote Iceberg REST endpointYes
warehouseThe catalog to select on that endpoint. In the Iceberg REST specification this value identifies the catalogNo

For every other backend, warehouse is a storage location such as s3://{bucket}/{prefix}. For a REST backend it is a catalog name, because that is what the Iceberg REST specification uses it for. A remote server that exposes several catalogs under one URI needs this value to know which one you mean, and a server that exposes only one does not.

Gravitino never writes data for a federated catalog and never needs a storage location of its own, so no warehouse path is configured on this side.

Pass the caller's identity​

A REST backend always forwards the caller's authorization header to the remote catalog. Gravitino takes the header value from the authenticated principal and places it on every outgoing request, so the remote catalog sees the end user rather than a shared service account.

Forwarding is unconditional for this backend and cannot be turned off. Requests made by a principal that carries no token fail with an error stating that the principal has no authorization header value, so an anonymous or unauthenticated caller cannot reach a federated catalog at all.

What the remote catalog must accept​

The header is forwarded exactly as it arrived. Gravitino does not exchange the token, re-sign it, or request a new one on the caller's behalf. A caller who signs in with Basic credentials therefore has its user name and password sent to the remote catalog, so use OAuth tokens with federated catalogs. Both servers therefore have to accept the same token, which means both trust the same identity provider and the remote catalog accepts the audience the token was issued for.

The usual failure is the audience. A token minted for Gravitino carries Gravitino's audience claim, and a remote catalog that validates audience strictly rejects it. Either register one application in the identity provider that both servers accept, or configure the remote catalog to accept the audience Gravitino uses.

Configure authentication on the Gravitino side as described in How to authenticate.

Authorize federated access​

By default, a Gravitino Iceberg REST service that proxies to a REST backend does not run its own authorization checks. The downstream catalog performs them, and skipping the local check avoids evaluating the same request twice.

Set gravitino.iceberg-rest.disable-rest-authz to false to have Gravitino authorize the request against its own model before proxying. The two checks then both apply, and a caller needs the privilege in Gravitino as well as at the remote catalog. Set it under gravitino.additionalConfigItems in my-values.yaml; see Set other server properties.

ValueBehavior
trueOnly the remote catalog authorizes the request. The default
falseGravitino authorizes the request first, then proxies it to the remote catalog

The skip applies only when the catalog's backend is genuinely a REST catalog. Every other backend is authorized locally regardless of this setting. See Privileges for the Gravitino privilege model.

Request vended credentials​

Federated tables are read with credentials the remote catalog issues, because it owns the storage configuration. Set data-access on the catalog to ask for them, and Gravitino sends the matching Iceberg access delegation header on each table load.

ValueEffect
vended-credentialsThe remote catalog returns scoped storage credentials with the table
remote-signingThe remote catalog signs storage requests instead of handing out credentials

Any other value is rejected when the catalog is created. If the property is left unset, no delegation header is sent and the client falls back to whatever storage credentials it already has.

For how Gravitino vends credentials for the catalogs it owns, see Credential vending.

Tune the connection​

A federated catalog adds a network hop to every metadata operation, so the client timeouts matter more than they do for a local backend.

PropertyMeaningDefault
rest-client-connection-timeout-msTime allowed to establish the HTTP connection10000
rest-client-socket-timeout-msTime allowed between bytes on the connection60000

Set table-metadata-cache-impl to an empty string on a federated catalog. The table metadata cache needs a backend that can report a table's metadata location, and a REST catalog cannot. Leaving the default in place is harmless but logs a warning at catalog load and disables the cache anyway.

Limitations​

Gravitino proxies the Iceberg REST protocol and adds nothing to it, so a federated catalog carries the following constraints.

Storage configuration belongs to the remote catalog, and the credentials and file IO settings on the Gravitino catalog do not apply to federated tables. Audit coverage is split, with Gravitino recording the request it received and the remote catalog recording what it did with the request. Table maintenance and statistics run against catalogs Gravitino owns and do not reach federated tables. Tags and policies attached in Gravitino describe the federated metadata but are not visible to a client that talks to the remote catalog directly.

Use the API​

Federated catalogs are created, altered, and dropped through the standard catalog endpoints.

OperationMethodPath
Create catalogPOST/api/metalakes/{metalake}/catalogs
Load catalogGET/api/metalakes/{metalake}/catalogs/{catalog}
Alter catalogPUT/api/metalakes/{metalake}/catalogs/{catalog}
Drop catalogDELETE/api/metalakes/{metalake}/catalogs/{catalog}

See Catalogs and schemas for the full request and response payloads, and Iceberg catalog for the properties shared by all Iceberg catalog backends.