Section 9

9. Bring your own key (BYOK)

Live and isolating since 2026-09-13. A tenant's Claude calls are signed by its own Anthropic account; the router logs credential_source: byok_tenant for them and platform_env for everyone else, so one provider account's billing state cannot take another tenant down.

Storing a credential needs keys:write on the calling key. A key cannot grant itself that scope; ask an operator to set it through PATCH /internal/v1/tenant-keys/{id} first.

Account-scoped headers (anthropic-workspace-id, openai-organization, openai-project) travel only with Nozzle's own credential. Your key carries your key and the API version and nothing of ours — so a workspace that exists in Nozzle's provider account is never asserted against yours.

bash
curl -X POST "$BASE/v1/byok/credentials" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"provider": "anthropic", "api_key": "sk-ant-…"}'

Keys are validated against the provider before storage, then sealed with authenticated encryption bound to your tenant and provider — a row copied to another tenant fails to decrypt. Only the last four characters are ever readable back.

Resolution order per request: your credential first, then a Nozzle key from the database, then the environment. So BYOK is an override on top of platform keys, not a replacement.

GET /v1/byok/credentialslist (last4 only)
POST /v1/byok/credentials/{id}/rotatereplace, re-validated and re-sealed
DELETE /v1/byok/credentials/{id}hard delete, no ciphertext remains