secret-store: the anthropic proxy secret moves in too

Third value for the store, agreed in conversation. Neither an encryption nor a
signing key — a bearer credential the agent presents to the proxy on localhost —
but it qualifies on the same properties: generated once, shared between two core
processes, fatal to regenerate silently.

It makes the case better than the other two, because it is not in .env. It is in
$DATA_PATH/sidecar/claude-state.json, which is the exact location decision 3
rules out by name: DATA_PATH is what gets backed up.

Also records the rename. ANTHROPIC_API_KEY is wrong in both halves — not
Anthropic's, not an API key; Anthropic's real credential is the OAuth token in
~/.claude/.credentials.json that the proxy swaps this one for. It is
anthropic-proxy-secret everywhere we control, and keeps the CLI's name only on
the assignment `claude` itself reads.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 22:52:23 +00:00
co-authored by Claude Opus 5
parent cb67b22f80
commit 32af97e260
+18
View File
@@ -116,6 +116,24 @@ one value — or comes from a file read on demand.
- `JWT_SECRET` — a signing key rather than an encryption key, but it has the same properties: must - `JWT_SECRET` — a signing key rather than an encryption key, but it has the same properties: must
survive restarts, must never be regenerated silently, and benefits from versioning during a rotation. survive restarts, must never be regenerated silently, and benefits from versioning during a rotation.
Leaving one in a store and one in `.env` would be the scattering this is meant to end. Leaving one in a store and one in `.env` would be the scattering this is meant to end.
- **The anthropic proxy secret**, purpose `anthropic-proxy`. Agreed 2026-08-12. Neither an encryption
key nor a signing key — a bearer credential, generated once by `ensureProxySecret` and presented by
`officer-agent` to `officer-anthropic-proxy` on `127.0.0.1`. It qualifies on the same three
properties: generated once, shared between two processes, fatal to regenerate silently.
It is in the store for a sharper reason than the other two, though. It is not in `.env` today — it
is in `$DATA_PATH/sidecar/claude-state.json`, mixed in with session records. That is the one
location [decision 3](#3-where-the-file-goes) rules out by name: `DATA_PATH` is what people back up,
so the secret already travels in the same tarball as the data it protects.
**Naming.** It is called `ANTHROPIC_API_KEY` in `ensureAnthropicEnv`, and that name is wrong in both
halves — it is not Anthropic's and it is not an API key. Anthropic's real credential is the OAuth
token in `~/.claude/.credentials.json`, which the proxy swaps this one for on the way out. Our name
for it is **anthropic-proxy-secret** everywhere we control.
The exception is the last line before the spawn. `claude` reads the variable `ANTHROPIC_API_KEY` and
format-checks the `sk-ant-api03-` prefix, so both are the CLI's contract rather than ours and both
stay. That one assignment keeps the CLI's name, with a comment saying why.
--- ---