Help · section 20 of 44
DAB & API Keys
Mirrors the in-app Help. The live copy in your console and `dlake guide help` are always current.
The Data Engine (DAB) is a per-tenant container serving REST + GraphQL over the entities an admin exposes (Global Scope tab). Key points:
- Per-entity settings (gear icon): addressable key for views, column aliases, GraphQL relationships, custom REST path/methods, GraphQL include/exclude, response cache TTL. For a stored procedure the gear also carries Expose as MCP tool — see Stored Procedures as MCP Tools.
- Computed columns & URL-ready keys: computed
idcolumns make rows addressable as/api/<entity>/id/<value>; computed columns are excluded from write bodies automatically in the config. - Writing data: POST=insert, PATCH=partial upsert (preferred), PUT=full-replace upsert; never send
id/TimeStamp/dl_*; CP tables needdl_expected_tsechoed on UPDATE; PUT/PATCH need create+update permissions. - API keys: generated per user, optionally scoped per entity/action/field. Exchange
dlk_key → JWT at the Auth API. A key inherits every right the owning user has and is then narrowed by a per-key denylist — open the key’s rights panel (Settings → API Keys → the key) and uncheck any capability you don’t want that key to carry (the effective right ismin(user, key), recomputed from the live user whenever the key is minted or refreshed, so removing a right from the user removes it from the key too). Owner (is_owner, full access to the tenant) and DBO Admin (is_dbo_admin, administration of thedboschema) are shown separately and are individually deniable per key — issue a key that can’t act as owner even though its user is one. Revoking a key kills its live MCP sessions and is enforced at token validation, so revocation takes effect promptly. Inactive (revoked/expired) keys can be soft-deleted from the list. Each key card also has an Extend menu (+7 / +30 / +90 days / +6 months) that pushes the expiry out — new expiry ismax(now, current) + interval, so extending a live key never shortens it and an expired (but not revoked) key revives from now; a revoked key can’t be extended. A revoked key shows a Restore action that un-revokes it — this clears the revoked flag only and does not change the expiry, so a key that was also past its expiry comes back still-expired and prompts you to Extend it before it works again. When an admin clicks Generate Key, an Owner picker lets them mint the key on behalf of another user (the key then acts as that user); non-admins can only create keys for themselves, and even an admin can’t target a more-privileged account (only an owner can target an owner, only a DBO Admin a DBO Admin). Projects: keys can be organized into projects (a first-class grouping entity, with future per-project billing / cost-limits in mind). The Generate Key dialog has a Project field — a typeahead over existing projects where you can also type a new name to create one on the fly; leave it blank for no project. The API Keys page groups key rows under a project header (“No project” for ungrouped keys), with a project filter dropdown at the top, and each key’s action menu has a Move action that files it under a project (get-or-create by name, case-insensitive) or clears it. Projects are organizational only — they are not a rights axis and never change what a key can do.
Warning — a scoped key doesn’t work until DAB is restarted. DAB learns a key’s per-key role (
key_<id>) only when its config is regenerated, so between saving a scope and the next restart every Data API call with that key fails403 AuthorizationCheckFailedeven though the key, the scope, and the entities are all correct. Saving a key’s scope here deliberately does not restart the engine (restarts stay batched and user-initiated) — the page raises a “Restart Needed” notice, and you press Restart DAB when you’re ready. From the CLI/MCP the same step isdlake admin restart_dab --confirm true. Unscoped/full-access keys are unaffected (they use the shareddatalake_userrole, which DAB already knows), and revoking a key is the deliberate exception — it regenerates immediately so the dead key’s role disappears at once.
The scope entry shape (for the CLI/MCP
create_api_key --scope/set_key_entity_scopes, matching this page’s grid): each entry is{ "entityName": "<table/view/procedure>" }plus one or more action booleans —canRead,canCreate,canUpdate,canDelete,canExecute— with an optionalschemaNamefor a lake/external table (omit it for the working schema). There is noentitykey (rejected as “empty entityName”) and no bareread/writekey (rejected as “no actions selected”). Example:[{"entityName":"pizza_menu_items","canRead":true},{"entityName":"usp_PlaceOrder","canExecute":true}]. Notedlake keys createmints unscoped keys only — scoped keys come from this page ordlake admin create_api_key --scope @scope.json.
- MCP connector URLs: an AI client connects to the data plane at the per-tenant
https://datalake-ms-dab.commercient.com/auth/<tenant>/mcp, or at the generic tenant-lesshttps://datalake-ms-dab.commercient.com/mcp. The generic URL carries no tenant in the path — it resolves the tenant from the credential, in order: the OAuth JWT’s tenant (bound when the user enters their domain on the authorize page), a composite API keytenant:dlk_...(inX-API-Key, orAuthorization: Bearer/ApiKey), or anX-Tenant: <slug>header sent with a plaindlk_key. Everything downstream is identical either way (same tools, port lookup, lockout, token cache) — the only difference is who names the tenant.- Which credential: prefer the API-key header —
X-API-Key: <tenant>:dlk_...on the generic URL is a complete authentication, so Claude Code, thedlakeCLI, editor clients and your own apps need no OAuth, no client registration and no callback URL. OAuth exists for hosted connector UIs (claude.ai, Claude Desktop’s connector UI) that cannot send a custom header; it collects the same key and hands back a token standing for it, so it grants nothing extra. - Which to use: the generic URL is the one-connector-definition-for-any-customer option — hand out a single URL and the key identifies the tenant. Use a per-tenant URL when the tenant is fixed, or — the headline case — when one Claude/MCP client needs several Data Lake tenants connected at the same time: clients like Claude Desktop / claude.ai dedupe connectors by normalized URL, so each tenant needs its own distinct URL (
…/auth/acme/mcp,…/auth/globex/mcp, …) to live as a separate connector. With OAuth the per-tenant URL also pre-selects that tenant on the authorize page. Suggested connector names: Commercient Data Lake \ Data Hub (data) and Commercient Data Lake \ Data Hub Admin (admin). A stuck/“expired” connector record can be worked around with a URL variant like…?client=v2.
- Which credential: prefer the API-key header —
- MCP sessions (admin): every OAuth-connected agent session is listed and can be terminated.
- Config history: every engine config version is recorded (who/when/what); any version can be viewed, diffed, and reverted to.
- Engine management: Restart DAB rebuilds the config and redeploys the container; the Resources tab shows live container CPU/memory/network stats. Schema DDL (creating/altering/dropping tables, views, procedures) never auto-restarts the engine — batch your changes and click Restart DAB when ready.
- Host mode (seeing the real error): the data plane deliberately returns a generic “While processing your request the database ran into an error” for SQL failures. Switching host mode to
developmentmakes the engine return the underlying SQL error instead — the fastest way to diagnose a failing entity, a constraint violation, or a bad stored procedure. It applies on the next Restart DAB (the page flags the pending restart). Switch it back toproductionwhen you’re done: it is tenant-wide and the detail is not meant for end users. - Relationships (for the GraphQL surface): declaring a relationship is what lets an application developer read a parent and its children in one nested GraphQL request, and filter by a related entity’s column. It is a Data-API concern only — it creates no database foreign key and changes nothing for the SQL editor, the Data Browser, MCP or the CLI. See the API Usage Guide for the developer-facing detail.
- Atomic multi-row writes: Data-API writes are not transactional — a multi-step write (header + lines + a status row) can half-succeed and leave orphans. When you need all-or-nothing, wrap the work in a stored procedure (
BEGIN TRAN/COMMIT/ROLLBACK) and expose it as an entity; one call then either commits everything or leaves the database untouched. Procedure entities are exposed onPOSTonly, since a write must not be reachable by a “safe” method.