diff --git a/agent/managed-skills/git-repo-secret-audit/SKILL.md b/agent/managed-skills/git-repo-secret-audit/SKILL.md index 9f07df2..8504b75 100644 --- a/agent/managed-skills/git-repo-secret-audit/SKILL.md +++ b/agent/managed-skills/git-repo-secret-audit/SKILL.md @@ -19,6 +19,8 @@ for p in (home/".config/secrets").iterdir(): if m: vals.add(m.group(1)) known[p.name] = {v for v in vals if len(v) >= 12} ``` +Also add every secret the repo itself embeds (e.g. credentials living in a *test helper*) +by concatenating its quoted fragments, then search for the joined value. Report ONLY `value[:4] + len + sha256[:10]`. Never print a value, and never quote a secret-shaped literal in a doc/commit message — the pre-commit gate will (correctly) block it. @@ -41,6 +43,19 @@ git status --porcelain -uall --ignored=matching # !! lines: on-disk ignored fi git config --list --show-origin # local/global/system credentials git ls-files | grep -E '(auth\.json|trust\.json|\.env|\.pem|\.key|identity)' # quarantine ``` +**Invocation forms that actually work** (each of these cost a wasted round-trip): +- `git grep --all -F ''` — the options MUST precede the pattern; `git grep -l -F '' --all` + treats `--all` as a pathspec and silently returns 0 lines. Grepping a *fragment* (not the full + value) is what catches split-concatenation disguises like `"Assf.""1234"`. +- `git ls-tree -r --format=... ` works for ONE rev; pass several revs and it emits nothing, + no error. For sha→path across all refs use `git rev-list --objects --all`, which yields + `" "` lines directly. +- `git cat-file --batch` fed with `rev-list --objects` lines echoes `sha path` headers, so naive + header parsing misaligns and content is lost. Feed bare SHAs in chunks, or use + `git cat-file --batch-all-objects --batch` and parse `" blob \n\n"` records. +- Check every worktree/checkout: `git -C rev-parse HEAD` often differs from the + audited worktree, so the leak may exist on `main` while the audited tree looks clean. + LFS: scan `.git/lfs/objects/**` as BYTES (`decode("latin-1")`) — a screenshot is a classic secret carrier and the tracked tree holds only pointers. @@ -53,6 +68,9 @@ Flag every one whose value is in `known` as a LIVE leak; list the rest for triag - prose: `Set password: user.set_password(...)`, `authenticate(user, password)` - 40-hex hits that are git object ids / packfile names (`pack-<40hex>.pack`) - memory/KB records that *describe* a secret operation +- length-threshold gates that miss short passwords: a check like + `len(val) >= 24 and re.fullmatch(...)` clears a real 12-char password, so a passing + secret-scan test proves nothing about short credentials A hit is a leak only when the value matches a live secret, decodes to a real credential, or sits in a field a program reads. @@ -61,8 +79,12 @@ Check file modes of the secret dir (`0600`, dir `0700`) — world-readable secre most common real finding. Then grep the live values across shell rc files, `~/.gitconfig`, `~/.npmrc`, `~/.netrc`, `~/.curlrc`, `~/.docker/config.json`, `~/.cache/huggingface/token`, `~/.aws/credentials`, `~/.ssh/config` and report filenames only. +Also check files the deployer *generates* on hosts: a script that writes a credential file +without `chmod 600` (while sibling writes in the same script do chmod) is the same class. ## 6. Report Per layer: scope numbers + verdict. Every hit: path:line, redacted value, verdict (leak / benign + why). Name the gate's coverage gap if the project's own hook misses shapes you matched. Fix modes/chmod on the spot; changes to a security hook are the operator's call. +A secret in git history is only removable by rotation or history rewrite — say so, don't +imply an edit fixes it. diff --git a/agent/memories/sharpshooter/wt-20261019-125509-7c8a99d-me8scwe1t2nf/state.json b/agent/memories/sharpshooter/wt-20261019-125509-7c8a99d-me8scwe1t2nf/state.json index b412fdb..2d85cc6 100644 --- a/agent/memories/sharpshooter/wt-20261019-125509-7c8a99d-me8scwe1t2nf/state.json +++ b/agent/memories/sharpshooter/wt-20261019-125509-7c8a99d-me8scwe1t2nf/state.json @@ -1,6 +1,6 @@ { "v": 1, - "lastConsolidatedAt": 1792597305986, + "lastConsolidatedAt": 1792601206018, "lastResult": { "at": 1792573818108, "sessions": 1, diff --git a/agent/memories/sharpshooter/wt-20261020-125416-6d1fc1f-3cjcsma2m7gk5/state.json b/agent/memories/sharpshooter/wt-20261020-125416-6d1fc1f-3cjcsma2m7gk5/state.json index c98ff4f..b22d25e 100644 --- a/agent/memories/sharpshooter/wt-20261020-125416-6d1fc1f-3cjcsma2m7gk5/state.json +++ b/agent/memories/sharpshooter/wt-20261020-125416-6d1fc1f-3cjcsma2m7gk5/state.json @@ -1,6 +1,6 @@ { "v": 1, - "lastConsolidatedAt": 1792597521722, + "lastConsolidatedAt": 1792600941734, "lastResult": { "at": 1792574016725, "sessions": 1, diff --git a/agent/memories/sharpshooter/wt-20261020-144605-e7c60f6-31xsw83t7yjc6/state.json b/agent/memories/sharpshooter/wt-20261020-144605-e7c60f6-31xsw83t7yjc6/state.json index d90c709..4ed4472 100644 --- a/agent/memories/sharpshooter/wt-20261020-144605-e7c60f6-31xsw83t7yjc6/state.json +++ b/agent/memories/sharpshooter/wt-20261020-144605-e7c60f6-31xsw83t7yjc6/state.json @@ -1,6 +1,6 @@ { "v": 1, - "lastConsolidatedAt": 1792597538935, + "lastConsolidatedAt": 1792601138964, "lastResult": { "at": 1792556461435, "sessions": 1, diff --git a/agent/memories/sharpshooter/wt-20261020-155034-1b9ba40-iffz605wjz2v/state.json b/agent/memories/sharpshooter/wt-20261020-155034-1b9ba40-iffz605wjz2v/state.json index 91f90b8..e02c79c 100644 --- a/agent/memories/sharpshooter/wt-20261020-155034-1b9ba40-iffz605wjz2v/state.json +++ b/agent/memories/sharpshooter/wt-20261020-155034-1b9ba40-iffz605wjz2v/state.json @@ -1,6 +1,6 @@ { "v": 1, - "lastConsolidatedAt": 1792597290296, + "lastConsolidatedAt": 1792601190359, "lastResult": { "at": 1792566095222, "sessions": 1, diff --git a/agent/memories/sharpshooter/wt-20261021-021543-6d1fc1f-o9a35ouamphx/state.json b/agent/memories/sharpshooter/wt-20261021-021543-6d1fc1f-o9a35ouamphx/state.json index 53fb430..ad8406f 100644 --- a/agent/memories/sharpshooter/wt-20261021-021543-6d1fc1f-o9a35ouamphx/state.json +++ b/agent/memories/sharpshooter/wt-20261021-021543-6d1fc1f-o9a35ouamphx/state.json @@ -1,4 +1,4 @@ { "v": 1, - "lastConsolidatedAt": 1792597483840 + "lastConsolidatedAt": 1792601083860 }