key-gaps: the key regex was blind to digits, inventing missing secrets #69
3 changed files with 17 additions and 3 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
# Claude Code worktrees. These are other sessions' checkouts living inside this
|
||||
# repo; `git add -A` will otherwise commit them as embedded git repositories.
|
||||
.claude/worktrees/
|
||||
|
|
@ -34,8 +34,18 @@ Gather the key names over SSH (never the values), then audit. Hosts/keys per INF
|
|||
K=~/.ssh/thermograph_agent_ed25519
|
||||
# sudo: /etc/thermograph.env is root-owned (0640). On prod `agent` can read it
|
||||
# directly too, but sudo works uniformly on both boxes.
|
||||
ssh -i $K agent@169.58.46.181 'sudo grep -oE "^[A-Z_]+=" /etc/thermograph.env' > /tmp/prod.keys # prod
|
||||
ssh -i $K agent@75.119.132.91 'sudo grep -oE "^[A-Z_]+=" /etc/thermograph.env' > /tmp/beta.keys # beta
|
||||
#
|
||||
# The character class must allow DIGITS. This was `^[A-Z_]+=` until 2026-07-24,
|
||||
# which silently skipped every key whose name contains a digit — in this estate
|
||||
# that is all six *_S3_* keys. Prod audited as 26 keys against 32 real ones, and
|
||||
# the audit reported the S3 credentials as missing from both hosts. They were
|
||||
# present the whole time, and the phantom was independently "confirmed" twice by
|
||||
# people re-running the same pattern. An audit that under-reports is worse than
|
||||
# no audit: the invented finding sends someone to provision a credential that
|
||||
# already exists, and it was briefly recorded as a root cause of a real bug.
|
||||
# The match still stops at the `=`, so no value is ever read.
|
||||
ssh -i $K agent@169.58.46.181 'sudo grep -oE "^[A-Z][A-Z0-9_]*=" /etc/thermograph.env' > /tmp/prod.keys # prod
|
||||
ssh -i $K agent@75.119.132.91 'sudo grep -oE "^[A-Z][A-Z0-9_]*=" /etc/thermograph.env' > /tmp/beta.keys # beta
|
||||
python3 .claude/skills/key-gaps/key_gaps.py prod=/tmp/prod.keys beta=/tmp/beta.keys
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ It reads only KEY NAMES, never values — safe to run anywhere. Sources per envi
|
|||
* a SOPS-encrypted YAML (deploy/secrets/<env>.yaml) — keys are plaintext even when
|
||||
encrypted, so no age key or decryption is needed; or
|
||||
* a plain key-list file (one KEY per line, or KEY=... lines) — e.g. the output of
|
||||
`ssh <box> 'grep -oE "^[A-Z_]+=" /etc/thermograph.env'` for a live audit.
|
||||
`ssh <box> 'grep -oE "^[A-Z][A-Z0-9_]*=" /etc/thermograph.env'` for a live audit.
|
||||
|
||||
Usage:
|
||||
key_gaps.py prod=deploy/secrets/prod.yaml beta=deploy/secrets/beta.yaml
|
||||
|
|
|
|||
Loading…
Reference in a new issue