ANTHROPIC_API_KEY Revocation Playbook

Service: Anthropic Claude API (https://console.anthropic.com) Secrets: ANTHROPIC_API_KEY, RADEK_BRAND_ANTHROPIC_API_KEY Operation type: REVOCATION — old key deleted, NO replacement key issued Triggered by: Incident #2970 (docker inspect exposure on bms-4) Scheduled time: 21:00 CEST on 2026-07-06 (19:00 UTC)

2026-07-06 approach change: Instead of rotating (revoke + replace), the old key will be revoked only at console.anthropic.com. No replacement key will be issued. Services that relied on this key will stop calling the Anthropic API — this is acceptable:

  • audit-engine (bms-4) — not deployed, no impact
  • n8n brand workflows (bms-4) — automation pauses, acceptable
  • et-operational-platform AI features (Vercel) — features pause, acceptable
  • personal brand content automation — pauses, acceptable

A new key will be added in a future session when Anthropic API features are re-enabled. Until then, the key entries are removed from all SOPS files so no stale value persists.


Login credentials (Anthropic Console)

  • URL: https://console.anthropic.com/settings/keys
  • Email: radieu@gmail.com
  • Auth: Google SSO (Sign in with Google)

Affected files and consumers

Full inventory — all three files must have the key removed.

SOPS fileServer / targetContainer / serviceEnv varImpact on revocation
secrets/n8n-bms4.env.sopsbms-4audit-engineANTHROPIC_API_KEYNo impact (not deployed)
secrets/n8n-bms4.env.sopsbms-4n8n, n8n-worker-1/2/3RADEK_BRAND_ANTHROPIC_API_KEYBrand automation stops — acceptable
secrets/et-operational-platform.env.sopsVercel prj_ziLl911FOYLAeukQujL4NjxR4eWyet-op Next.js appANTHROPIC_API_KEYAI features in et-op stop — acceptable
radekkonarski-personal-brand/secrets/radekkonarski-brand.env.sopspersonal brand n8ncontent automation workflowsANTHROPIC_API_KEYContent automation stops — acceptable

GH Secrets: ANTHROPIC_API_KEY is NOT stored as a GH Secret (verified 2026-07-06 — no action needed there).

Not affected (these unset the key — enforcement, not consumers):

  • scripts/spawn-worker.shunset ANTHROPIC_API_KEY before claude-runner
  • scripts/spawn-infra-task-worker.sh — same
  • scripts/run-nightly-triage.sh — same; also warns to Discord if key leaks into shell
  • scripts/queue-analyst.pyenv.pop("ANTHROPIC_API_KEY", None) before Claude CLI
  • GH Actions nightly-devops-triage.yml, resource-incident-triage.yml — same

Key multiplicity: Verify at console.anthropic.com whether ANTHROPIC_API_KEY and RADEK_BRAND_ANTHROPIC_API_KEY are the same underlying key or two different keys. Revoke both / all keys that were exposed. Note the key name(s) / ID(s) in the audit log.


Pre-revocation checklist

  • Confirm this is the correct playbook (revoke only, no replacement)
  • Confirm Anthropic console access at https://console.anthropic.com/settings/keys
  • Confirm $env:SOPS_AGE_KEY_FILE = "C:\Users\konar\.age\p24-infra-keys.txt" will be set
  • Note down: which key names / IDs will be revoked (visible in console before revocation)
  • Have this playbook open alongside a terminal window during execution

Step 0 — Create backup (MANDATORY before any SOPS write)

$env:SOPS_AGE_KEY_FILE = "C:\Users\konar\.age\p24-infra-keys.txt"
$timestamp = Get-Date -Format 'yyyyMMdd-HHmm'
$backupDir = "C:\tmp\anthropic-revoke-backup-$timestamp"
New-Item -ItemType Directory -Force $backupDir | Out-Null
 
# p24-infra SOPS files
Copy-Item "C:\code_2026\p24-infra\secrets\n8n-bms4.env.sops"               "$backupDir\n8n-bms4.env.sops"
Copy-Item "C:\code_2026\p24-infra\secrets\et-operational-platform.env.sops" "$backupDir\et-operational-platform.env.sops"
 
# Personal brand SOPS file (different repo)
Copy-Item "d:\code_2026\radekkonarski-personal-brand\secrets\radekkonarski-brand.env.sops" `
          "$backupDir\radekkonarski-brand.env.sops"
 
# Verify all 3 backups decrypt
sops --decrypt --input-type dotenv --output-type dotenv "$backupDir\n8n-bms4.env.sops" | Out-Null
if ($LASTEXITCODE -ne 0) { throw "n8n-bms4 backup canary FAILED" }
sops --decrypt --input-type dotenv --output-type dotenv "$backupDir\et-operational-platform.env.sops" | Out-Null
if ($LASTEXITCODE -ne 0) { throw "et-op backup canary FAILED" }
sops --decrypt --input-type dotenv --output-type dotenv "$backupDir\radekkonarski-brand.env.sops" | Out-Null
if ($LASTEXITCODE -ne 0) { throw "radekkonarski-brand backup canary FAILED" }
 
Write-Host "Backup created at: $backupDir"
Write-Host "Files backed up: $((Get-ChildItem $backupDir).Count)"
Write-Host "BACKUP TIMESTAMP: $timestamp   <-- save this for rollback"

Do not proceed past Step 0 until all 3 canaries pass.


Step 1 — Human action: revoke key(s) at Anthropic console

This step is manual — Claude cannot access the Anthropic console.

  1. Navigate to https://console.anthropic.com/settings/keys
  2. Sign in with Google (radieu@gmail.com)
  3. Identify the key(s) currently active:
    • Check both ANTHROPIC_API_KEY and RADEK_BRAND_ANTHROPIC_API_KEY — they may be the same underlying key or two separate keys
  4. Note the key name(s) / ID(s) for the audit log (first 8–10 chars is enough to identify)
  5. Delete / revoke each exposed key
  6. Confirm: revoked keys show status “Deleted” or “Revoked” in console
  7. Signal Claude to proceed to Step 2

Step 2 — Remove key entries from SOPS files (3 files)

For each file: decrypt → remove ANTHROPIC lines → re-encrypt → canary. Reference: docs/playbooks/sops-edit-operations.md (canonical Windows-safe write pattern).

Important: the lines are removed entirely (not zeroed out). No placeholder value.

2a. secrets/n8n-bms4.env.sops — remove both ANTHROPIC keys

$env:SOPS_AGE_KEY_FILE = "C:\Users\konar\.age\p24-infra-keys.txt"
Set-Location "C:\code_2026\p24-infra"
$SOPS_FILE  = "$PWD\secrets\n8n-bms4.env.sops"
$TEMP_PLAIN = "$PWD\secrets\n8n-bms4-edit-tmp.env.sops"
$TEMP_ENC   = "$PWD\secrets\n8n-bms4-enc-tmp.env.sops"
 
$plain = sops --decrypt --input-type dotenv --output-type dotenv $SOPS_FILE
if ($LASTEXITCODE -ne 0) { throw "Decrypt failed" }
 
# Remove both ANTHROPIC lines entirely
$lines = $plain | Where-Object {
    $_ -notmatch "^ANTHROPIC_API_KEY=" -and
    $_ -notmatch "^RADEK_BRAND_ANTHROPIC_API_KEY="
}
$content = ($lines -join "`n") + "`n"
$plain = @()
 
[System.IO.File]::WriteAllText($TEMP_PLAIN, $content, [System.Text.UTF8Encoding]::new($false))
$content = ""
 
sops --encrypt --input-type dotenv --output-type dotenv --output $TEMP_ENC $TEMP_PLAIN
if ($LASTEXITCODE -ne 0) {
    @($TEMP_PLAIN, $TEMP_ENC) | Where-Object { Test-Path $_ } | Remove-Item -Force
    throw "Encrypt failed"
}
Remove-Item $TEMP_PLAIN -Force -ErrorAction SilentlyContinue
 
sops --decrypt --input-type dotenv --output-type dotenv $TEMP_ENC | Out-Null
if ($LASTEXITCODE -ne 0) {
    Remove-Item $TEMP_ENC -Force -ErrorAction SilentlyContinue
    throw "SOPS canary FAILED on temp — production file NOT touched"
}
 
Move-Item $TEMP_ENC $SOPS_FILE -Force
sops --decrypt --input-type dotenv --output-type dotenv $SOPS_FILE | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Production canary FAILED — restore from backup" }
Write-Host "n8n-bms4.env.sops: ANTHROPIC keys removed, canary passed."

2b. secrets/et-operational-platform.env.sops — remove ANTHROPIC_API_KEY

$env:SOPS_AGE_KEY_FILE = "C:\Users\konar\.age\p24-infra-keys.txt"
Set-Location "C:\code_2026\p24-infra"
$SOPS_FILE  = "$PWD\secrets\et-operational-platform.env.sops"
$TEMP_PLAIN = "$PWD\secrets\et-operational-platform-edit-tmp.env.sops"
$TEMP_ENC   = "$PWD\secrets\et-operational-platform-enc-tmp.env.sops"
 
$plain = sops --decrypt --input-type dotenv --output-type dotenv $SOPS_FILE
if ($LASTEXITCODE -ne 0) { throw "Decrypt failed" }
 
$lines = $plain | Where-Object { $_ -notmatch "^ANTHROPIC_API_KEY=" }
$content = ($lines -join "`n") + "`n"
$plain = @()
 
[System.IO.File]::WriteAllText($TEMP_PLAIN, $content, [System.Text.UTF8Encoding]::new($false))
$content = ""
 
sops --encrypt --input-type dotenv --output-type dotenv --output $TEMP_ENC $TEMP_PLAIN
if ($LASTEXITCODE -ne 0) {
    @($TEMP_PLAIN, $TEMP_ENC) | Where-Object { Test-Path $_ } | Remove-Item -Force
    throw "Encrypt failed"
}
Remove-Item $TEMP_PLAIN -Force -ErrorAction SilentlyContinue
 
sops --decrypt --input-type dotenv --output-type dotenv $TEMP_ENC | Out-Null
if ($LASTEXITCODE -ne 0) {
    Remove-Item $TEMP_ENC -Force -ErrorAction SilentlyContinue
    throw "SOPS canary FAILED on temp"
}
 
Move-Item $TEMP_ENC $SOPS_FILE -Force
sops --decrypt --input-type dotenv --output-type dotenv $SOPS_FILE | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Production canary FAILED — restore from backup" }
Write-Host "et-operational-platform.env.sops: ANTHROPIC_API_KEY removed, canary passed."

2c. radekkonarski-brand.env.sops (personal brand repo)

$env:SOPS_AGE_KEY_FILE = "C:\Users\konar\.age\p24-infra-keys.txt"
$BRAND_REPO = "d:\code_2026\radekkonarski-personal-brand"
$SOPS_FILE  = "$BRAND_REPO\secrets\radekkonarski-brand.env.sops"
$TEMP_PLAIN = "$BRAND_REPO\secrets\radekkonarski-brand-edit-tmp.env.sops"
$TEMP_ENC   = "$BRAND_REPO\secrets\radekkonarski-brand-enc-tmp.env.sops"
 
$plain = sops --decrypt --input-type dotenv --output-type dotenv $SOPS_FILE
if ($LASTEXITCODE -ne 0) { throw "Decrypt failed" }
 
$lines = $plain | Where-Object { $_ -notmatch "^ANTHROPIC_API_KEY=" }
$content = ($lines -join "`n") + "`n"
$plain = @()
 
[System.IO.File]::WriteAllText($TEMP_PLAIN, $content, [System.Text.UTF8Encoding]::new($false))
$content = ""
 
sops --encrypt --input-type dotenv --output-type dotenv --output $TEMP_ENC $TEMP_PLAIN
if ($LASTEXITCODE -ne 0) {
    @($TEMP_PLAIN, $TEMP_ENC) | Where-Object { Test-Path $_ } | Remove-Item -Force
    throw "Encrypt failed"
}
Remove-Item $TEMP_PLAIN -Force -ErrorAction SilentlyContinue
 
sops --decrypt --input-type dotenv --output-type dotenv $TEMP_ENC | Out-Null
if ($LASTEXITCODE -ne 0) {
    Remove-Item $TEMP_ENC -Force -ErrorAction SilentlyContinue
    throw "SOPS canary FAILED on temp"
}
 
Move-Item $TEMP_ENC $SOPS_FILE -Force
sops --decrypt --input-type dotenv --output-type dotenv $SOPS_FILE | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Production canary FAILED — restore from backup" }
Write-Host "radekkonarski-brand.env.sops: ANTHROPIC_API_KEY removed, canary passed."

Step 3 — Commit and push (both repos)

3a. p24-infra repo

Set-Location "C:\code_2026\p24-infra"
git add secrets\n8n-bms4.env.sops secrets\et-operational-platform.env.sops
git commit -m "security(#2970): remove ANTHROPIC_API_KEY from SOPS — key revoked
 
Key revoked at console.anthropic.com (incident #2970 docker inspect exposure).
Removed from: n8n-bms4.env.sops (both ANTHROPIC_API_KEY + RADEK_BRAND_ANTHROPIC_API_KEY)
              et-operational-platform.env.sops (ANTHROPIC_API_KEY)
No replacement key issued — Anthropic API features will pause until re-enabled.
Affected: n8n brand workflows (bms-4), et-op AI features (Vercel). Acceptable.
 
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"
git push origin main

3b. Personal brand repo

Set-Location "d:\code_2026\radekkonarski-personal-brand"
git add secrets\radekkonarski-brand.env.sops
git commit -m "security: remove ANTHROPIC_API_KEY from SOPS — key revoked (#2970)
 
Key revoked at console.anthropic.com. No replacement key issued.
Content automation workflows will pause until a new key is added.
 
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"
git push origin main

Step 4 — Trigger secrets-sync to push removal to live servers

# Sync bms-4: removes key from /opt/p24-infra/bms-4/.env + restarts affected containers
gh workflow run secrets-sync.yml --repo radieu/p24-infra -f target=bms-4
 
# Sync Vercel: removes ANTHROPIC_API_KEY from et-op Vercel env vars
gh workflow run secrets-sync.yml --repo radieu/p24-infra -f target=et-operational-platform

Monitor at https://github.com/radieu/p24-infra/actions. Both should complete green within 5–8 minutes.


Step 5 — Smoke tests

These verify that services are still operational after key removal. AI features will stop — that is expected and acceptable.

5a. bms-4 — n8n still healthy

# Run from Windows dev or SSH tunnel to bms-4
curl -s https://n8n.srv1072950.hstgr.cloud/healthz
# Expected: {"status":"ok"} — n8n container starts fine without the Anthropic key

5b. bms-4 — audit-engine (not deployed)

Not deployed — skip.

5c. et-operational-platform — app still serves

$r = Invoke-WebRequest -Uri "https://et-op.vercel.app/api/health" -UseBasicParsing -ErrorAction SilentlyContinue
Write-Host "et-op health: $($r.StatusCode)"
# Expected: 200 — app serves normally; AI-specific routes may return 500/disabled, acceptable

5d. Personal brand n8n

Brand workflows that call Anthropic will fail on next trigger — this is expected and acceptable. No action needed.


Rollback (if a critical non-AI service breaks unexpectedly)

Only use if a service that should NOT depend on the Anthropic key breaks. AI-specific features failing is expected, not a rollback trigger.

# Replace YYYYMMDD-HHMM with the timestamp from Step 0
$backupDir = "C:\tmp\anthropic-revoke-backup-YYYYMMDD-HHMM"
$env:SOPS_AGE_KEY_FILE = "C:\Users\konar\.age\p24-infra-keys.txt"
 
# Restore p24-infra files
Copy-Item "$backupDir\n8n-bms4.env.sops"               "C:\code_2026\p24-infra\secrets\n8n-bms4.env.sops" -Force
Copy-Item "$backupDir\et-operational-platform.env.sops" "C:\code_2026\p24-infra\secrets\et-operational-platform.env.sops" -Force
 
# Canary on restored files
sops --decrypt --input-type dotenv --output-type dotenv "C:\code_2026\p24-infra\secrets\n8n-bms4.env.sops" | Out-Null
if ($LASTEXITCODE -ne 0) { throw "n8n-bms4 restore canary FAILED — manual recovery needed" }
sops --decrypt --input-type dotenv --output-type dotenv "C:\code_2026\p24-infra\secrets\et-operational-platform.env.sops" | Out-Null
if ($LASTEXITCODE -ne 0) { throw "et-op restore canary FAILED — manual recovery needed" }
 
# Commit rollback
Set-Location "C:\code_2026\p24-infra"
git add secrets\n8n-bms4.env.sops secrets\et-operational-platform.env.sops
git commit -m "security: ROLLBACK ANTHROPIC_API_KEY removal — unexpected breakage
 
Restoring SOPS files from backup. Investigate which non-AI service broke.
NOTE: The key was already revoked at console.anthropic.com — restoring to SOPS
does NOT restore API functionality. A new key must be generated separately.
 
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"
git push origin main
 
# Redistribute via secrets-sync
gh workflow run secrets-sync.yml --repo radieu/p24-infra -f target=bms-4
gh workflow run secrets-sync.yml --repo radieu/p24-infra -f target=et-operational-platform
 
# Restore personal brand if it was also updated
Copy-Item "$backupDir\radekkonarski-brand.env.sops" `
          "d:\code_2026\radekkonarski-personal-brand\secrets\radekkonarski-brand.env.sops" -Force
Set-Location "d:\code_2026\radekkonarski-personal-brand"
git add secrets\radekkonarski-brand.env.sops
git commit -m "security: ROLLBACK ANTHROPIC_API_KEY removal — unexpected breakage"
git push origin main

CRITICAL NOTE on rollback: restoring the SOPS files puts the old (now-revoked) key back in SOPS and on servers. This will NOT restore AI functionality — the key is dead at Anthropic’s side. The rollback is only useful for diagnosing unexpected non-AI failures. To re-enable AI features later, a completely new key must be generated and added via the normal secret-manager flow.


Timeline (21:00 CEST start)

TimeStepWho
21:00Step 0 — backup 3 SOPS filesClaude
21:02Step 1 — revoke key(s) at console.anthropic.comHuman
21:05Step 2 — remove from 3 SOPS files + canary eachClaude (secret-manager)
21:15Step 3 — commit + push both reposClaude
21:16Step 4 — trigger secrets-sync (bms-4 + et-op)Claude
21:25Step 5 — smoke testsClaude + Human
21:30Done or rollback decision

Post-revocation log entry

Append to docs/secrets-rotation-log.md after completion:

| 2026-07-06 19:00 UTC | ANTHROPIC_API_KEY | n8n-bms4.env.sops, et-operational-platform.env.sops, radekkonarski-brand.env.sops | REVOKED — incident #2970 docker inspect exposure. No replacement key. | claude | key deleted at console; removed from SOPS; secrets-sync pushed removal to bms-4 + Vercel |
| 2026-07-06 19:00 UTC | RADEK_BRAND_ANTHROPIC_API_KEY | n8n-bms4.env.sops | REVOKED — same incident #2970 | claude | key deleted at console; removed from SOPS; n8n containers restarted |

Re-enabling Anthropic API (future)

When Anthropic API features need to be re-activated:

  1. Generate a new key at https://console.anthropic.com/settings/keys
  2. Follow docs/playbooks/secret-manager.md — add new key to the same 3 SOPS files
  3. Run secrets-sync for affected targets
  4. Update this playbook: add new “Last active” entry at the top

  • docs/playbooks/secret-manager.md — SOPS operation patterns and distribution chain
  • docs/playbooks/sops-edit-operations.md — Windows-safe SOPS write pattern (canonical)
  • docs/playbooks/static-api-key-incident-rotation.md — Incident SLA and escalation
  • docs/playbooks/credential-rotation-policy.md — Tier definitions and SLAs
  • docs/playbooks/server-ssh-connectivity.md — bms-4 SSH connection patterns (post-Phase5 VPN)