By default, the Datris OSS install accepts unauthenticated requests on the REST and MCP APIs — fine for laptop development, wrong for any shared or hosted setup. Turn on API-key authentication and every caller (the UI, the CLI, agent MCP clients) must present a key that the platform recognizes. This page covers single-tenant deployments. Multi-tenant setups use the same flag and a different mapping mechanism — see user-auth and the Configuration → Tenants screen.Documentation Index
Fetch the complete documentation index at: https://docs.datris.ai/llms.txt
Use this file to discover all available pages before exploring further.
What it does
WhenUSE_API_KEYS=true:
- Programmatic clients (CLI, MCP-connected agents, external scripts) must include
x-api-key: <value>on every request. - The platform validates the value against a known set of issued keys.
- The capability framework enforces what each scoped key is allowed to do (see the capability model). Calls outside the key’s scope return HTTP 403.
- The Datris UI behavior depends on whether user authentication is also enabled. With
USE_USER_AUTH=true(recommended), the UI authenticates via session cookie alone — no API key is sent or required. With user-auth off, the UI falls back to the legacy “paste a key” prompt on first load.
USE_USER_AUTH but they’re paired conceptually — see the supported matrix below.
Enabling it
The recommended setup pairsUSE_API_KEYS=true with USE_USER_AUTH=true (see the matrix below for why).
1. Flip the flags
In.env:
2. Restart
3. Use the platform
- The UI: log in with your admin account. The session cookie authenticates browser flows — no
x-api-keyis sent, no Connect prompt appears. The Assistant inherits your session for capability checks; its tool calls and audit log are taggedsession:<your username>. - Programmatic clients (CLI, MCP agents, scripts): each one needs its own key, issued from Configuration → API-Keys. See the issuance flow below.
Legacy mode (USE_USER_AUTH=false, USE_API_KEYS=true)
If you can’t or don’t want to enable user-auth, the UI falls back to the older “paste a key” flow:
- The Connect prompt appears on first load
- The default seeded value is
default-ui-key(defined indocker/vault-init.sh); paste it once - Browser stores it in localStorage; subsequent loads skip the prompt
- Rotate it any time from Configuration → API-Keys → ui → Rotate (the new value is mirrored automatically into the validation map, and the operator distributes it out of band)
Issuing keys for CLI, MCP, and other clients
Open Configuration → API-Keys → Issue new key.- Pick a label (
cli,claude-desktop,cursor,prod-loader, etc.) — lowercase, hyphens/underscores ok. - Pick a template or build a capability list manually:
- read-only — observer access to pipelines/taps/jobs/metadata + query/search
- rag-builder — create pipelines/taps in a catalog, upload documents, run vector search
- reporting — analyst-shaped read access
- ops — run any tap or pipeline, kill stuck jobs, no edits
- full-access — legacy
*:*shape; avoid for agents
- Review and create.
- Copy the value immediately — it’s shown once. The platform stores a hashed copy; the plaintext is not retrievable after this modal closes.
- Paste the value into the agent’s MCP client config (or CLI env var, etc.).
The Vault label
ui is reserved for the seeded fallback UI key (used in legacy USE_USER_AUTH=false mode and for the Assistant’s internal MCP-to-REST hop). You don’t issue this one from the UI — it’s seeded by vault-init.sh on first boot and rotated from the API-Keys tab like any other key.Supported configurations
USE_API_KEYS and USE_USER_AUTH compose into four states:
USE_USER_AUTH | USE_API_KEYS | Behavior |
|---|---|---|
false | false | Full anonymous. No prompts, no auth, no gating. OSS default; fine for laptop dev. |
true | true | UI gated by login; programmatic clients gated by key. Recommended for shared installs. |
true | false | UI gated by login; programmatic clients are anonymous. Workable, slightly odd. |
false | true | Refused at boot. No coherent auth mechanism for the browser. Pick a different combination. |
Rotating a key
From the API-Keys tab in Configuration, click Rotate on any row:- A new value is generated server-side
- The validation map (
oss/api-keys) and operator-facing record are updated in sync - The new value is shown once in a copy-to-clipboard modal
- Distribute the new value out of band to whoever was using it; they’ll get 401s on their next request and need the new value
Revoking a key
From the API-Keys tab, click Revoke. The key’s metadata is marked revoked; the underlying value stays inoss/api-keys so failed auth attempts log as “revoked key” rather than “unknown key” — useful for tracking compromised credential reuse.
Revoked keys cannot be un-revoked. Issue a new key instead.
How requests get logged
Each authenticated request emits a structured line in the datris container log:route— HTTP method + pathrequired— the capability the route needs (see the capability model)key— the label of the API key (orsession:<username>for cookie-authed UI flows)legacy=true— the key has full access via the backward-compatibility backstop;falsemeans a scoped keyoutcome—grant,would-deny,deny, orunmapped
outcome=deny and an HTTP 403. To trial a new scope policy without rejecting traffic — for example, you’ve issued a new scoped key and want to see what it would have been denied under real workload before pointing a production agent at it — set CAPABILITY_ENFORCEMENT=log-only in .env. The same calls then succeed and emit outcome=would-deny log lines instead of 403s. Flip back to enforce (or remove the line) once you’ve validated the policy.
The capability model
Every API key carries a list of capability strings:resource:action[:scope]. Scope segments restrict by container (catalog, database, collection), type, or ownership — never by leaf resource name, since agents pick those at runtime.
When user-auth is on, logged-in browser sessions are first-class identities too: session:admin, session:editor1, etc. The capability bundle is derived from the user’s role (admin → full access, editor → create/update/run, viewer → read-only). The API-Keys tab in Configuration shows scoped keys; per-role capabilities are managed via the Users tab.
Multi-tenant
MULTI_TENANT=true switches the model: a single api-key-mappings secret maps keyValue → tenantEnv, and every tenant carries its own per-environment data. The UI key flow above is single-tenant only; see the Configuration → Tenants documentation for the multi-tenant equivalent.
See also
- User Authentication — login + roles for the UI
- Configuration Reference — full env var list
- MCP Server — how external agents connect
