Skip to content

Admin key

The admin key gates the dashboard and admin-only endpoints on your customer-stack Function App. It’s a single shared secret — anyone with it has full read+write access to your stack’s admin surface.

What it gates

  • GET /api/dashboard — the HTML admin dashboard
  • GET /api/cost, /api/sessions, /api/sessions/{id}/transcript — admin-only data endpoints
  • POST /api/ops/rotate-key — the rotate endpoint itself
  • GET /api/teams-app.zip, /api/teams-setup — Teams app generator

What it does NOT gate:

  • GET /api/plan — anonymous (used by the dashboard JS + future docs site)
  • GET /api/health — anonymous (deploy probe)
  • POST /api/chat, /api/chat/stream — visitor chat (uses a different visitor JWT)
  • POST /api/agent/* — agent endpoints use the customer’s own AAD app for SSO

How to use it

Two ways to authenticate:

  1. Query string?code=<key> appended to the URL. The dashboard JS uses this when you first arrive with ?code= in the URL, then drops it on subsequent navigations (cookies take over).

  2. Authorization headerAuthorization: Bearer <key>. Used by API integrations.

  3. Httponly session cookie — set automatically when you log in with a key. Survives until you sign out or rotate the key.

Where it’s stored

The admin key lives in two places:

  • Customer Key Vault as admin-key (canonical; rotated in-place).
  • Function App env var ADMIN_KEY (fallback when KV is unreachable).

The customer-runtime reads from KV first (5-second cache), falling back to env. When you rotate, the KV value updates and the env stays as a stale fallback until the next deploy.

How to rotate

The dashboard has a Rotate admin key button (admin-only). Clicking it:

  1. Generates a new 48-character hex value.
  2. Writes it to KV as the new admin-key secret value.
  3. Shows the new key once on screen for you to save.
  4. Invalidates all existing sessions (cookies signed with the old key fail signature check).

You’ll need to re-log-in with the new key. Old ?code= links die immediately.

Recovering a lost key

If you’ve lost the admin key with no fallback session:

Terminal window
az keyvault secret show \
--vault-name pocaikv{your-stack-hash} \
--name admin-key \
--query value -o tsv

You’ll need Key Vault Secrets User on the customer KV. The deploy doesn’t grant that role to your account by default — it’s only on the customer Function App’s MI.

If you’ve also lost KV access: grant yourself Key Vault Secrets User via the customer RG (which you have Reader on as the Managed App owner), then re-fetch:

Terminal window
az role assignment create \
--role "Key Vault Secrets User" \
--assignee "$(az account show --query user.name -o tsv)" \
--scope $(az keyvault show -n pocaikv{stack-hash} --query id -o tsv)

Wait ~30 seconds for RBAC to propagate, then re-fetch.