Merge pull request #922 from Molecule-AI/infra/issue-894-anthropic-api-key-docs

docs(infra): document ANTHROPIC_API_KEY as required global secret (closes #894)
This commit is contained in:
Hongming Wang 2026-04-17 21:40:23 -07:00 committed by GitHub
commit 581ccefe89
2 changed files with 43 additions and 1 deletions

View File

@ -89,7 +89,7 @@ NEXT_PUBLIC_PLATFORM_URL=http://localhost:8080
NEXT_PUBLIC_WS_URL=ws://localhost:8080/ws NEXT_PUBLIC_WS_URL=ws://localhost:8080/ws
# Workspace Runtime # Workspace Runtime
ANTHROPIC_API_KEY= ANTHROPIC_API_KEY= # Anthropic API key (console.anthropic.com). Required for MODEL_PROVIDER=anthropic (default). Also used by workspaces that call the Anthropic SDK directly (e.g. molecule-hitl, hermes runtime). Register as a global secret via POST /settings/secrets so it is auto-propagated to all workspace containers — do NOT set only as a workspace-level secret or SDK-direct workspaces will silently fail with 401. See docs/runbooks/saas-secrets.md#anthropic_api_key.
OPENROUTER_API_KEY= # OpenRouter API key (openrouter.ai). Use with model: openrouter:anthropic/claude-3.5-haiku. Also acts as the fallback key for the hermes runtime when HERMES_API_KEY is unset. OPENROUTER_API_KEY= # OpenRouter API key (openrouter.ai). Use with model: openrouter:anthropic/claude-3.5-haiku. Also acts as the fallback key for the hermes runtime when HERMES_API_KEY is unset.
HERMES_API_KEY= # Nous Research Portal API key (inference-prod.nousresearch.com). Used by the hermes runtime; falls back to OPENROUTER_API_KEY if unset. HERMES_API_KEY= # Nous Research Portal API key (inference-prod.nousresearch.com). Used by the hermes runtime; falls back to OPENROUTER_API_KEY if unset.
GROQ_API_KEY= # Groq API key (console.groq.com). Use with model: groq:llama-3.3-70b-versatile GROQ_API_KEY= # Groq API key (console.groq.com). Use with model: groq:llama-3.3-70b-versatile

View File

@ -17,6 +17,7 @@ update doesn't silently break production.
| `STRIPE_API_KEY` | `fly secrets` on `molecule-cp` | `sk_live_…` secret key used by `internal/billing.StripeProvider` for customer/subscription/checkout mutations + GDPR Art. 17 cascade | | `STRIPE_API_KEY` | `fly secrets` on `molecule-cp` | `sk_live_…` secret key used by `internal/billing.StripeProvider` for customer/subscription/checkout mutations + GDPR Art. 17 cascade |
| `STRIPE_WEBHOOK_SECRET` | `fly secrets` on `molecule-cp` | `whsec_…` used by `internal/billing.verifySignature` to reject forged webhook calls. Rotated independently from the API key — Stripe treats them as separate secrets | | `STRIPE_WEBHOOK_SECRET` | `fly secrets` on `molecule-cp` | `whsec_…` used by `internal/billing.verifySignature` to reject forged webhook calls. Rotated independently from the API key — Stripe treats them as separate secrets |
| `GITHUB_TOKEN` | Built-in GitHub Actions token | GHCR push; rotated automatically | | `GITHUB_TOKEN` | Built-in GitHub Actions token | GHCR push; rotated automatically |
| `ANTHROPIC_API_KEY` | **Global secret** via `PUT /settings/secrets` on each tenant platform instance | Default LLM provider (`MODEL_PROVIDER=anthropic`). Must be set as a **global** secret so it propagates to all workspace containers — workspace-level-only is not sufficient for SDK-direct workspaces (e.g. molecule-hitl). See [rotation procedure below](#anthropic_api_key). |
## Coupled secrets — MUST rotate together ## Coupled secrets — MUST rotate together
@ -175,6 +176,47 @@ For `STRIPE_WEBHOOK_SECRET`:
5. Wait for the overlap window to expire or click "Delete old secret" 5. Wait for the overlap window to expire or click "Delete old secret"
in Stripe dashboard. in Stripe dashboard.
## Rotation procedure — ANTHROPIC_API_KEY
This key is set as a **platform global secret** (not a Fly secret). It propagates
automatically to every non-paused workspace container via the Phase 15 global-secrets
fan-out (`PUT /settings/secrets` triggers auto-restart of all affected workspaces).
Per-workspace overrides (e.g. a workspace with its own `ANTHROPIC_API_KEY` secret)
shadow the global value — the per-workspace value takes precedence.
1. Generate a new key at [console.anthropic.com](https://console.anthropic.com) →
API Keys → Create key. Name it `molecule-<env>-rotation-$(date +%Y%m%d)`.
2. Set the new key as a global secret on each platform instance:
```bash
# Self-hosted (local/staging)
curl -X PUT http://localhost:8080/settings/secrets \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"key":"ANTHROPIC_API_KEY","value":"sk-ant-api03-..."}'
# SaaS control plane — set on the tenant platform via control-plane API
# (details TBD when molecule-cp exposes a /cp/orgs/:id/secrets endpoint)
```
The platform auto-restarts every non-paused workspace on set.
3. Verify: restart one workspace and confirm it starts up without 401 errors:
```bash
curl -X POST http://localhost:8080/workspaces/$WORKSPACE_ID/restart \
-H "Authorization: Bearer $ADMIN_TOKEN"
# Watch logs — no "401 unauthorized" from Anthropic SDK should appear
```
4. Revoke the old key in the Anthropic console once all workspaces have restarted.
### Blast-radius note
Rotating `ANTHROPIC_API_KEY` restarts **every non-paused workspace** on the
instance. Schedule rotation during low-traffic windows. Paused workspaces pick
up the new key when they are next resumed (secrets are injected at container
start, not from the running container env).
## Emergency contacts ## Emergency contacts
- **Fly**: billing dashboard at fly.io → Support - **Fly**: billing dashboard at fly.io → Support