From 925f04acdb5e1f7ddf3d6bd3f132fc2933336d45 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Thu, 13 Aug 2026 21:56:28 +0000 Subject: [PATCH] fix(agentsmd-audit): scope secrets-scanner placeholder allowlist to matched token validate-secrets.sh checked the placeholder allowlist regex against the whole line before running any secret-pattern regex. An unrelated placeholder-looking token anywhere on the line (e.g. "example" or "your-token-here" in a trailing comment) suppressed detection of a real credential earlier on the same line. Scope the allowlist check to the matched secret-candidate substring only, which the per-match re-check already did downstream but the whole-line pre-check short-circuited before it ever ran. Extend validate-secrets.bats with a case proving a real AWS-style key is still caught when a placeholder token sits elsewhere on the line. Regenerate the flat-mirror copy at plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh via scripts/sync-plugin-content.sh --all per ADR-0016. --- .../agentsmd-audit/scripts/validate-secrets.sh | 8 ++++---- .../agentsmd-audit/tests/validate-secrets.bats | 13 +++++++++++++ .../agentsmd-audit/scripts/validate-secrets.sh | 8 ++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/plugins/core/.apm/skills/agentsmd-audit/scripts/validate-secrets.sh b/plugins/core/.apm/skills/agentsmd-audit/scripts/validate-secrets.sh index c8cb2f0..6bf88b8 100755 --- a/plugins/core/.apm/skills/agentsmd-audit/scripts/validate-secrets.sh +++ b/plugins/core/.apm/skills/agentsmd-audit/scripts/validate-secrets.sh @@ -87,14 +87,14 @@ for fpath in find_agents_md(repo_root): with open(fpath, encoding="utf-8", errors="replace") as f: lines = f.readlines() for i, line in enumerate(lines, start=1): - if PLACEHOLDER_RE.search(line): - continue for label, pattern in PATTERNS: m = pattern.search(line) if not m: continue - # Re-check placeholder allowlist against just the matched value, in case - # the placeholder marker sits outside the regex's own match span. + # Scope the placeholder allowlist to the matched secret-candidate + # substring only. Checking the whole line would let an unrelated + # placeholder-looking token elsewhere on the line (e.g. in a + # trailing comment) suppress detection of a real credential. value = m.group(0) if PLACEHOLDER_RE.search(value): continue diff --git a/plugins/core/.apm/skills/agentsmd-audit/tests/validate-secrets.bats b/plugins/core/.apm/skills/agentsmd-audit/tests/validate-secrets.bats index 8ff01a6..481fb63 100644 --- a/plugins/core/.apm/skills/agentsmd-audit/tests/validate-secrets.bats +++ b/plugins/core/.apm/skills/agentsmd-audit/tests/validate-secrets.bats @@ -52,6 +52,19 @@ EOF assert_output --partial "connection string" } +@test "still catches a real secret when a placeholder token sits elsewhere on the same line" { + cat > "$TMPDIR/AGENTS.md" <<'EOF' +# AGENTS.md + +## Setup +- AWS_ACCESS_KEY_ID=AKIAABCDEFGHIJKLMNOP # see your-token-here for an example, gitleaks:allow (synthetic fixture — this test verifies the placeholder allowlist is scoped to the matched value, not the whole line) +EOF + run bash "$SCRIPT" "$TMPDIR" + assert_failure + assert_output --partial "AWS access key ID" + assert_output --partial "AGENTS.md:4" +} + @test "detects secrets in a nested AGENTS.md, not just root" { mkdir -p "$TMPDIR/packages/api" cat > "$TMPDIR/AGENTS.md" <<'EOF' diff --git a/plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh b/plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh index c8cb2f0..6bf88b8 100755 --- a/plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh +++ b/plugins/core/skills/agentsmd-audit/scripts/validate-secrets.sh @@ -87,14 +87,14 @@ for fpath in find_agents_md(repo_root): with open(fpath, encoding="utf-8", errors="replace") as f: lines = f.readlines() for i, line in enumerate(lines, start=1): - if PLACEHOLDER_RE.search(line): - continue for label, pattern in PATTERNS: m = pattern.search(line) if not m: continue - # Re-check placeholder allowlist against just the matched value, in case - # the placeholder marker sits outside the regex's own match span. + # Scope the placeholder allowlist to the matched secret-candidate + # substring only. Checking the whole line would let an unrelated + # placeholder-looking token elsewhere on the line (e.g. in a + # trailing comment) suppress detection of a real credential. value = m.group(0) if PLACEHOLDER_RE.search(value): continue