DreamLake

15 · Token lifecycle

The auth code path exercised end to end on a control plane that is not in open mode. An admin token mints a client token, the CLI saves it, and a Python worker consumes it from the environment.

Starting with a new server? Follow Setting Up Lakeshore Service for the full setup sequence.

Exercises

  • LAKESHORE_ADMIN_TOKEN on the control-plane side — admin-bearer validation.
  • lakeshore admin tokens create — the explicit mint path.
  • lakeshore auth login — both the --token path and the admin-mint-on-the-fly path, saving to auth.yml.
  • LAKESHORE_CLIENT_TOKEN — the env var the Python worker reads, independent of auth.yml.

Requires

  • A control plane with LAKESHORE_ADMIN_TOKEN set (so it is not in open mode). For details, see Auth and secrets.
  • LAKESHORE_URL unset while you test the token path — when it is set, non-auth commands send no bearer token at all.

Run

bash
export LAKESHORE_ADMIN_TOKEN=<admin-token-from-.env>

# ─── Option A: mint explicitly, then log in with the plaintext ───────
lakeshore admin tokens create cli-$USER
# prints the plaintext once, plus a ready-made `auth login` line

lakeshore auth login \
  --server http://localhost:8080 \
  --namespace dev \
  --token <plaintext-from-above>

# ─── Option B: let `auth login` mint and save in one step ────────────
# With LAKESHORE_ADMIN_TOKEN set and --token omitted, login mints a
# fresh per-namespace token itself. --name is the label base; the CLI
# appends a timestamp so re-running doesn't collide.
lakeshore auth login \
  --server http://localhost:8080 \
  --namespace dev \
  --name cli-$USER

lakeshore auth status     # expect authMode: token, namespace: dev

Then drive a worker from the environment alone — no auth.yml involved:

bash
unset LAKESHORE_ADMIN_TOKEN
export LAKESHORE_URL=http://localhost:8080
export LAKESHORE_NAMESPACE=dev
export LAKESHORE_CLIENT_TOKEN=$(grep '^token:' ~/.config/lakeshore/auth.yml | awk '{print $2}')

lakeshore worker once --queue default --dry-run   # prints the child argv
lakeshore worker once --queue default
`worker` ignores the saved login on purpose

lakeshore worker never reads ~/.config/lakeshore/auth.yml. The plane it drains has to come from --url / LAKESHORE_URL, and the token from --token / LAKESHORE_CLIENT_TOKEN. That is why this step re-exports the token explicitly rather than relying on step 1.

Expected output

lakeshore auth status:

Auth OK.
  config path: /Users/you/.config/lakeshore/auth.yml
  server:      http://localhost:8080
  namespace:   dev
  token:       dlk_abcd... (cli-you-2026-01-02T03-04-05)
  lastUsedAt:  2026-01-02T03:05:11.000Z
  authMode:    token

worker once starts, drains at most one job, and exits without authentication errors.

If it fails

SymptomLikely cause
error: LAKESHORE_ADMIN_TOKEN is required for admin commands.Not exported in this shell. Every admin subcommand hard-exits 1 without it.
mint failed (401) on auth loginThe control plane doesn't recognize the admin token. Make sure your shell value matches what the CP read from .env at boot, and restart the CP after changing .env.
whoami failed (403)The token is scoped to a different namespace than --namespace.
authMode: openThe CP booted with a blank LAKESHORE_ADMIN_TOKEN and enforces nothing. Set it and restart.
The worker authenticates as nobodyLAKESHORE_CLIENT_TOKEN is empty. Re-export it from auth.yml.

Status

Manual.

Loop back

That's the full cascade. Once all 15 are green you have working verification of every major surface. Re-run as features change.

→ Back to Overview