Metastore

How BullSequana AI catalogs tabular data and governs who can create and use it.

Agentic Friendly

BullSequana AI's metastore catalogs tabular data for each tenant. Tables belong to datasets, and datasets belong to spaces, the same personal and shared spaces used elsewhere in Data. Access to data assets is governed centrally by a tenant administrator.

What the metastore provides

  • A per-tenant catalog that holds every space, dataset, and table that tenant owns.
  • Personal spaces for a user's own data and shared spaces for a team's data, so ownership stays clear.
  • A single point of access control: granting a role on a space, dataset, or table applies consistently, so the grant a tenant administrator makes is the grant that governs the catalog.

Access roles

A tenant administrator grants a role on a space, dataset, or table. The supported roles depend on the resource scope:

RoleWhat it allows
ownerFull control, including deleting the object
editorCreate tables in a dataset, or modify an existing table
contributorWrite to an existing dataset (not available on individual tables)
viewerRead data
discovererSee that the object exists

Example: give a colleague access to a dataset

Say a tenant administrator wants to let a colleague, alice, create and query tables in a shared dataset called fraud.

Before you start

The platform operator must enable the metastore integration and configure this tenant's metastore project. The default warehouse and fraud dataset in this example must already exist; a role grant does not create them. Substitute your site's warehouse, dataset, and user identity.

The examples use user:alice@acme.com because the metastore subject claim is email. If the installation uses another subject claim, use that claim's exact value instead. Integrated metastore grants accept direct user:<id> subjects, not group subjects.

1. Grant access

The administrator grants Alice the editor role on the fraud dataset from their own Developer Workspace notebook, the same way any user in the tenant would call the platform's data helper library.

Example: grant the role
import bsqai_data
import requests

TUPLES_URL = "http://tuples.tuples.svc.cluster.local:8080"
token = bsqai_data.get_token()

response = requests.post(
    f"{TUPLES_URL}/api/v1/datasets/default/fraud/roles",
    headers={"Authorization": f"Bearer {token}"},
    json={"subject": "user:alice@acme.com", "relation": "editor"},
)
print(response.status_code)  # 201

A 201 response confirms the grant was recorded. With the tenant metastore integration configured, the request updates both authorization stores. Verify the effective access through Alice's catalog operation in the next step; a tenant without metastore integration writes only to the Data authorization store.

2. Use the access

Alice opens a Developer Workspace notebook. The platform authenticates her automatically using her existing platform sign-in, so there is no separate metastore login. From the notebook, she requests a catalog client for the tenant's data, confirms she can see fraud, and creates a table inside it.

Example: create a table
import bsqai_data
from pyiceberg.schema import Schema
from pyiceberg.types import NestedField, StringType, DoubleType, TimestampType

catalog = bsqai_data.get_catalog(warehouse="default")
print(catalog.list_namespaces())  # includes ("fraud",)

schema = Schema(
    NestedField(field_id=1, name="transaction_id", field_type=StringType(), required=True),
    NestedField(field_id=2, name="amount", field_type=DoubleType(), required=True),
    NestedField(field_id=3, name="event_time", field_type=TimestampType(), required=False),
)

table = catalog.create_table("fraud.transactions", schema=schema)
print(table)

3. Revoke access

Removing the role works the same way, with a DELETE request instead of a POST. This removes the direct grant; independent or inherited grants can still provide access. Verify the expected denial after revocation.

Example: revoke the role
response = requests.delete(
    f"{TUPLES_URL}/api/v1/datasets/default/fraud/roles",
    headers={"Authorization": f"Bearer {token}"},
    json={"subject": "user:alice@acme.com", "relation": "editor"},
)
print(response.status_code)  # 204

Diagnose a refused or incomplete change

  • 400: the subject or role is unsupported at that scope. For example, a group subject or contributor on an individual table is rejected before either store changes.
  • 404: the target warehouse, namespace, or table does not exist in the metastore.
  • 401 or 403: check the caller's authentication, selected tenant, and authority to manage the resource.
  • 500: ask the platform operator to inspect the authorization-service logs and compare both stores before treating the change as complete.

Integrated changes write to the metastore first, then the Data authorization store. A failure in the second write triggers a best-effort compensating change; the two stores do not share a transaction. If compensation also fails, an operator must reconcile them. Grant and revoke requests are idempotent, but retrying alone is not evidence that a reported inconsistency has been resolved.

On this page