SOPs
Handling Secrets
The Rule
Section titled “The Rule”Real credentials never go into the Claude Code chat. They go straight into secrets.json via VS Code, with a dummy value as a placeholder.
If a live key enters chat, it travels through Anthropic’s API and lives in the local session transcript forever. The dummy-then-edit flow keeps the key on disk only.
The Safe Flow
Section titled “The Safe Flow”When adding a new secret, the path is:
- Add a dummy entry via the CLI (so the env file syncs and the shape is in place):
Terminal window python3 ~/apps/cc/secrets/secrets_cli.py add STRIPE_DDXWEB_SECRET_KEY "REPLACE_ME_rk_live_xxx" - Open the JSON in VS Code:
Terminal window open -a "Visual Studio Code" ~/apps/cc/secrets/secrets.json - Paste the real value over the dummy. Save.
- Sync to regenerate
shared-secrets.env:Terminal window python3 ~/apps/cc/secrets/secrets_cli.py sync
Claude never sees the real value. The file is already in a path excluded from git.
Scope at Creation, Not at Storage
Section titled “Scope at Creation, Not at Storage”Splitting secrets into per-repo files sounds safer but usually is not. Shared credentials (Cloudflare, GHL, Google OAuth) get used by 5+ repos, so splitting just duplicates them or forces a lookup layer.
The higher-leverage move is scoping keys tightly when you create them:
- Stripe: use restricted keys. The “Authorizing an AI agent” flow in Stripe’s dashboard creates a key with only the permissions the agent needs (e.g.,
Products: Write,Prices: Write,Payment Links: Write, everything else blocked). Prefer this over the full secret key whenever possible. - Cloudflare: use API Tokens scoped to one zone or one permission (
Pages: Edit,DNS: Edit). Never the Global API Key for new work. Global API Key is full account access and should be treated as nuclear — kept only for scripts that genuinely need it, and rotated on any suspicion of exposure. - Google: per-app OAuth tokens, not shared. One stolen token equals one app compromised, not everything.
What Gets Stored Where
Section titled “What Gets Stored Where”- Source of truth:
~/apps/cc/secrets/secrets.json- Structured JSON with per-entry metadata (category, description, source URL, created date)
- Managed via
secrets_cli.py
- Legacy mirror:
~/apps/cc/secrets/shared-secrets.env- Regenerated on every
secrets_cli.py syncoradd - Never hand-edit — the change will be lost on the next sync
- Regenerated on every
- Neither file is committed to git. Both are gitignored in the cc repo and distributed across machines via
secrets-sync.sh(scp).
What to Do If a Key Leaks
Section titled “What to Do If a Key Leaks”If a real key ends up in chat, a git commit, or a public log:
- Rotate it immediately in the provider’s dashboard (Stripe, Cloudflare, etc.).
- Update the secret via
secrets_cli.py addwith the new value. - Do not try to scrub the transcript. Assume the leaked value is compromised and move on. Rotation is the only real fix.
Related
Section titled “Related”- Adding a Page to tms-internal
- Secrets CLI:
~/apps/cc/secrets/secrets_cli.py