Setup & configuration
Keys, profiles and the rules that keep them safe
Everything dlake does is tied to a tenant and an API key. This page explains how you get a key, how profiles keep tenants apart, why scoped keys need a restart, and which environment variables and argument forms the CLI understands.
How do I get a key?
In plain wordsA key is the password an app or a person uses with dlake. Your first one arrives when your Data Lake is created; after that you make more, each for a specific purpose.
1. The bootstrap key
When dlake register status --watch sees your Data Lake seeded, it prints a once-only, 7-day owner-admin key and saves it into a profile. Copy it; it is never shown again. It drives both the data plane and the admin control plane immediately.
2. Longer-lived keys
Mint them from the terminal or from the console under Settings → API Keys. dlake keys create mints an unscoped (full-access) key and prints it once. dlake admin create_api_key mints a scoped key limited to entities and actions (see below). Keys can be extended, revoked and restored; revocation takes effect immediately.
3. The welcome email
A second email carries the tenant owner's temporary password for the web console. Log in and change it. Those two emails are the whole human journey.
$ dlake keys create --name ci-reader --expires-days 90 --profile acme
dlk_... (shown once - store it now)
$ dlake keys list --profile acme
$ dlake keys revoke <id> --profile acme
Profiles: one per tenant
A profile stores the tenant slug, the key and a cached token. Since 0.5.7 there is no default profile: you name the tenant on every command with --profile, or set DLAKE_PROFILE once per shell session. The reason is safety: before that change a command could silently run against the wrong customer.
Give the key through DLAKE_API_KEY or --api-key-stdin. A plain --api-key flag still works but leaks to shell history and the process table.
$ DLAKE_API_KEY=dlk_... dlake login --domain acme --profile acme
$ dlake profiles list
$ export DLAKE_PROFILE=acme
$ dlake status
$ dlake logout --profile acme
Scoped keys: least privilege for apps and agents
In plain wordsA scoped key can only touch the tables and actions you list. The limit is enforced inside the database, so it holds even if the app is compromised.
A scope entry names an entity and one or more action booleans: canRead, canCreate, canUpdate, canDelete, canExecute, plus an optional schemaName for an external schema. REST PATCH/PUT by key need both canCreate and canUpdate. A scoped key cannot drive the admin control plane, and raw SQL is refused for it unless the key carries the AllowRawSql opt-in.
[
{ "entityName": "pizza_menu_items", "canRead": true },
{ "entityName": "usp_PlaceOrder", "canExecute": true }
]
$ dlake admin create_api_key --keyName pizza-web --expirationDays 180 --scope @scope.json
$ dlake admin restart_dab --confirm true
Roles
Tenant users hold Admin (everything), User (data read/write plus viewing schema objects) or ReadOnly. The sync-product command groups (CRMPro, Normal Sync, ODBC and API sync) require a key that belongs to an Admin user; otherwise the command says so and exits 3 without changing anything. Never ship a key to a browser: keep it in a small server-side proxy.
The canonical build sequence
In plain wordsCreate the tables, tell the API to serve them, restart it, load data, make a key for your app, restart again. The order matters.
# 1. authenticate with a FULL-SCOPE admin key
$ dlake login --domain acme --profile acme
$ dlake tool get_active_schema --profile acme
# 2. define schema (operates on the ACTIVE schema, usually DLO)
$ dlake admin create_table --tableName pizza_menu_items --columns @menu_items.json --primaryKey Sku
$ dlake admin create_procedure --procedureName usp_PlaceOrder --parameters @params.json --body @proc.sql
# 3. expose, then apply with a restart
$ dlake admin set_entity_exposure --entity pizza_menu_items --expose true
$ dlake admin set_entity_exposure --entity usp_PlaceOrder --expose true
$ dlake admin restart_dab --confirm true
# 4. now the data plane can see them
$ dlake tool create_record --entity pizza_menu_items ...
# 5. least-privilege key for the app, then restart again
$ dlake admin create_api_key --keyName pizza-web --expirationDays 180 --scope @scope.json
$ dlake admin restart_dab --confirm true
Things that bite on the way through
- The data plane sees only exposed entities. A table that exists but is not exposed and published returns
EntityNotFound. Raw SQL reads do not need exposure. - The active schema is read-only from the CLI. Read it with
get_active_schema; it is switched only from the console's schema dropdown. Qualify raw SQL (FROM DLO.table) and prefix object names per app. - Stored-procedure parameter names start with @, the type key is
dataType, and reserved T-SQL words (LineNo,Key,Order,User) fail as column names. - Data API writes are not transactional. Put multi-row writes in a stored procedure with
BEGIN TRAN/COMMIT, expose it, and call it as one POST. - ingest_table needs a natural-key primary key; seed identity-keyed tables with
create_record.
The dlake agent skill encodes all of this for coding agents.
Environment variables and flags
| Variable | Purpose |
|---|---|
DLAKE_PROFILE | Name the tenant profile once per shell session instead of passing --profile on every command. |
DLAKE_API_KEY | Supply the API key to dlake login without putting it on the command line. |
DLAKE_DOWNLOAD_BASE | Binary mirror base for npm installs (default: the Commercient download host). |
DLAKE_VERSION | Pin a specific binary version at npm install time (same or newer only). |
DLAKE_SHA256 | Operator-pinned expected digest (64 hex) for air-gapped installs. |
DLAKE_ALLOW_MIRROR_CHECKSUMS | Take SHA256SUMS from the mirror too (off by default; unsafe, prints a warning). |
DLAKE_ALLOW_DOWNGRADE | Permit an older DLAKE_VERSION than the installed package (off by default). |
DLAKE_S3_ACCESS_KEY_ID / DLAKE_S3_SECRET_ACCESS_KEY | Credentials for dlake s3 connections add, instead of interactive prompts or --*-stdin. |
--config-dir <dir> | Global flag: where profiles and cached tokens live. |
Global flags on every command: --json, --profile <name>, --config-dir <dir>. Login accepts per-profile --auth-url, --api-url and --mcp-url overrides.
Argument forms
- Scalars:
--tableName Invoice,--confirm true. - Arrays and objects: a value starting with
[or{is sent as JSON; a plain comma list still works for arrays of scalars. Malformed JSON is reported as a usage error naming the argument. @file: read the value from a file, for any argument. The reliable form on Windows.@@escapes a literal leading@.
Exit codes
0 | Success |
1 | Error |
2 | Usage error (bad flag or argument) |
3 | Permission or authentication denied |
Health checks in dlake status send no credential and judge each host on its own, so one blocked service never masks another.