Access and permissions

Everything in LakehouseBox belongs to an organisation. An organisation holds catalogs; a catalog holds namespaces; a namespace holds tables. Access is decided at two levels: a role in the organisation (what you may do to the organisation, its people and its tokens) and a grant on each catalog (what you may do to its data). The API also calls a catalog a warehouse (/v1/warehouses, warehouse_id). There are no per-namespace or per-table grants: a grant on a catalog covers every namespace and table in it.

Who can hold access

People log in on the account page with email and password and hold one of two roles, admin or member. The person who creates the organisation is its first admin.

Tokens are machine identities of the organisation: an agent, a script, a scheduled job. A token has its own API key, an organisation role (member by default) and its own catalog grants. A token never holds more than the person or token that created it: its role and its grants are capped by the creator's at creation and at every edit.

Organisation roles

capability admin member
see the organisation, its catalogs, members, tokens and usage yes yes
invite and remove members, change roles, claim domains, rename the organisation yes no
create a catalog yes yes, and gets write on it
rotate a catalog's credentials, delete, restore, publish or unpublish it yes no
grant or revoke read and write on every catalog only where they hold write, never above their own level, and only grants they made
create tokens any role, any grants member tokens, with grants up to their own
revoke tokens any the ones they created
read the audit log the organisation's events their own events

A token's role works exactly like a person's, with one difference: a human admin holds write on every catalog by role, while an admin token holds only its grants (it sees every catalog and may grant itself what it needs). The last human admin cannot leave, be removed or be demoted; tokens do not count as admins for this.

lhbox org list                                    # your organisations: name, id, your role
lhbox org members                                 # its people and their roles
lhbox org invite --email ana@example.com --role member
lhbox org role --principal <id> --role admin      # an organisation keeps at least one admin
lhbox org domain --domain example.com && lhbox org set --domain-join on

An invitation is valid for 7 days. The invitee follows the link in the mail, or runs the lhbox org accept --token <token> line the invite prints; an address with no account yet joins when it signs up. A domain can be claimed only by an admin whose own verified address is on it, never a public mail domain, and by one organisation only. With domain join on, a new account on that domain joins as a member. Removing a member also removes the grants they held.

Catalog grants: read and write

Each person or token holds read, write or nothing on each catalog:

  • A member holds read on every catalog of the organisation, by membership. An admin can revoke it catalog by catalog.
  • Whoever creates a catalog holds write on it.
  • A human admin holds write on every catalog.
  • A token holds exactly the grants it was given. With none, it can reach no catalog.

Read lets you list and query tables, get the catalog's read-only connection recipe, browse and preview the catalog's files, and list its uploaders and sinks. Write adds creating, changing and dropping tables, committing data, creating uploaders and sinks, and setting lifecycle rules and the catalog's default format version. The limit is enforced by the catalog and the store, not only by the API: a read credential is refused on every write.

lhbox catalog list                                # every catalog you can see, with your level on each
lhbox catalog grants sales                        # who holds what on it, and how (admin, membership, creator, explicit)
lhbox catalog grant sales --principal <id> --level read
lhbox catalog revoke sales --principal <id>

lhbox org members and lhbox token list show the principal ids; lhbox whoami shows your level on each catalog.

A catalog cannot be shared with another organisation. To let someone outside read it, send them the read-only recipe (lhbox connect --readonly --show-secrets), or have an admin make it public (lhbox catalog publish).

Tokens for agents

lhbox login is how an agent connects a machine. The CLI prints a link and a code; a person opens the link, logs in, and sees a consent screen naming the machine, the catalogs and the access asked for. They may lower the access to read or change the set of catalogs; they cannot give more than they hold themselves. On approval the organisation gets a new member token, named after the machine, holding exactly what was approved. The CLI saves its key to ~/.config/lhbox/credentials.json and never prints it (unless you pass --show-key). The code is valid for 15 minutes. The person who approved it, or an admin, can revoke it later on the account page (Access tokens, Connections).

lhbox login                                       # asks for write on the organisation's default catalog
lhbox login --catalog sales:read --catalog raw:write --name etl-box
lhbox login --no-wait                             # print the link and exit; finish later with --resume

lhbox token create makes a token by hand, for a program or an agent on a machine where nobody will run lhbox login. The API key is shown once; give it to the program as LHBOX_API_KEY.

lhbox token create --name nightly-load --grant sales:write --grant raw:read
lhbox token update nightly-load --grant sales:read   # the list replaces the current grants
lhbox token update nightly-load --role admin         # capped by your own role
lhbox token list
lhbox token revoke nightly-load

A token can create tokens within its own role and grants; revoking a token also revokes every token below it. The remote MCP server works the same way: approving it creates a token with its own grants.

The credentials an engine gets

An engine (DuckDB, PyIceberg, Spark and the others) does not use your API key. lhbox connect (or lhbox duckdb) hands it a connection recipe holding the catalog's own key pair: one read/write pair per catalog, and one read-only pair. You get the pair that matches your level; a write holder can ask for the read-only one with --readonly. The recipe masks the secret unless you pass --show-secrets.

From the key pair the engine gets two short-lived credentials and renews both itself:

  • a catalog token, valid for about an hour;
  • storage credentials, issued per table as the engine loads it, valid for about an hour. These are issued to write holders; a read-level recipe reads with the read-only key pair directly.

The key pair is the catalog's, not the token's: two machines connected to the same catalog at the same level get the same pair. Revoking a token or a grant stops what that token or person can do through LakehouseBox from then on, but a key pair already copied into an engine keeps working until an admin rotates the catalog.

Special-purpose credentials

Two credentials reach one path and nothing else; neither can read a table or use the catalog.

  • Uploaders are write-only keys for the catalog's file bucket, confined to one prefix: for a camera, a device or a partner that drops files. Creating one needs write on the catalog; the secret is shown once. See Uploaders.
  • Sink send keys can only post batches to one ingest sink, which LakehouseBox commits into one table. Creating a sink needs write; the key is shown once; deleting the sink revokes it. See Ingest.

Revoking and rotating

to stop do this takes effect
a machine or agent lhbox token revoke <name>, or the account page at once, for the token and every token it created
a person's or token's access to one catalog lhbox catalog revoke <catalog> --principal <id> at once, for new requests
a person an admin removes them from the organisation at once; their grants go too
an uploader lhbox catalog uploader revoke at once
a sink's send key lhbox sink delete at once
every copy of a catalog's key pair lhbox catalog rotate <catalog> (admin) old keys and catalog tokens made from them at once; storage credentials already issued run to their expiry, within about an hour

Rotate after revoking someone who had a copy of the recipe, and whenever a recipe may have leaked. Rotation can take a minute and replaces both pairs; every engine then needs a fresh recipe (lhbox connect again).

Deleting a catalog

Only an admin can delete a catalog, and the name must be typed out:

lhbox catalog delete sales --confirm sales
lhbox catalog restore sales                       # within the grace period

A deleted catalog stays restorable for a 7-day grace period. From the moment it is deleted it is gone for everyone: it leaves every list, its routes answer that it was deleted, its sinks are refused, and within seconds its key pairs and catalog tokens stop working and its uploaders are revoked. Storage credentials already issued run to their own expiry (about an hour). During the grace period the name stays reserved, the catalog no longer counts towards the number of catalogs you may have, and its bytes still count towards your storage.

lhbox catalog restore brings back the same catalog: its id, name, tables, files, settings and grants. It comes back private, without its uploaders, and with a new key pair, since the old one was revoked (run lhbox connect again).

When the grace period ends (the purge runs within a few hours), tables, files and credentials are deleted for good and the name is free. --purge skips or ends the grace period; nothing brings the catalog back after a purge.

The audit log

Grants, tokens, invitations, role changes, credential vending, rotations and deletions are recorded. Secrets are never written to it. A member sees their own events; an admin sees the whole organisation's with --org. Events are kept for 400 days.

lhbox audit --since 7d
lhbox audit --org <org> --action 'token.*' --limit 200

Every command is in the CLI reference; the routes are in the API reference.