feat(security): hardcoded secret/credential detection + git-history scan#17
Merged
Conversation
Add a repository-wide secret/credential scanner to the security suite that runs in both full scans and diff (PR) scans, and a command to scan git history. Detection tiers: - security.hardcoded-credential (fail): known provider formats — AWS, GitHub, GitLab, Slack (token + webhook), Stripe, Google, npm, PyPI, Docker Hub, SendGrid, Twilio, Azure, DB connection strings with embedded passwords, and Bearer tokens — plus config-defined custom_patterns - security.hardcoded-secret (warn): lower-confidence name-based heuristic (reclassified from fail) - security.high-entropy-string (warn, opt-in): Shannon-entropy detection of unknown/random secrets Config (security_rules.secrets): enabled, allow_paths, allow_patterns, custom_patterns, entropy. Values are masked in findings; placeholders and secret references (op://, vault://, $(...)) are skipped automatically. New `codeguard scan-history` walks git history for secrets that were committed and later removed (still leaked, need rotation), reusing the same scanner. Performance/hardening: a fast literal pre-filter gates the per-pattern regexes (~31x faster default scan, ~15x with entropy); binary/file-size/line-length caps bound work on untrusted PR input; history parsing avoids silent truncation on over-long lines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ssembly Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bound the hooks.slack.com webhook pattern with start/non-host-char on both sides (matching the repo's existing fix for go/regex/missing-regexp-anchor in quality_ai_style_drift.go) so an arbitrary host cannot precede or follow the match. The captured group is the webhook URL; detection behavior is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
alxxjohn
added a commit
that referenced
this pull request
Jun 30, 2026
🤖 I have created a release *beep* *boop* --- ## [0.6.0](v0.5.0...v0.6.0) (2026-06-30) ### Features * **security:** hardcoded secret/credential detection + git-history scan ([f2f6c61](f2f6c61)) * **security:** hardcoded secret/credential detection + git-history scan ([#17](#17)) ([c1afab7](c1afab7)) ### Bug Fixes * **security:** anchor Slack webhook regex to satisfy CodeQL ([52de05a](52de05a)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a repository-wide hardcoded secret/credential scanner to the
securitysuite that runs in both full scans and diff (PR) scans, plus a newcodeguard scan-historycommand. Replaces the previous single name-based regex.Detection tiers
security.hardcoded-credential(fail) — known provider formats: AWS, GitHub, GitLab, Slack (token + webhook), Stripe, Google, npm, PyPI, Docker Hub, SendGrid, Twilio, Azure storage keys, DB connection strings with embedded passwords, andAuthorization: Bearertokens — plus config-definedcustom_patterns.security.hardcoded-secret(warn) — lower-confidence name-based heuristic. Reclassified from fail → warn (high-confidence detection now lives in the credential rule).security.high-entropy-string(warn, opt-in) — Shannon-entropy detection of unknown/random secrets matching no known format.Config (
security_rules.secrets)enabled,allow_paths(globs),allow_patterns(regex),custom_patterns, andentropy(enabled/min_length/threshold/level). Findings show the value masked (AKIA…CDEF); placeholders and secret references (op://,vault://,$(...),${ENV}) are skipped automatically.codeguard scan-historyWalks git history for secrets that were committed and later removed (still leaked — need rotation), reusing the same scanner/allowlist. Supports
-all,-max-commits,-format json; exits non-zero onfail-level hits.Performance & hardening
strings.Containsproved ~85× faster than the equivalent regex alternation; a leading\b/(?i)defeats RE2's literal-prefix fast path.)bufio.Reader(notScanner) to avoid silent truncation on over-long lines.Testing
go test ./...green (7 packages);go vetandgofmtclean.cred(prefix, body)) so no contiguous real-format secret is committed — required for GitHub push protection and good practice in a secret-detection suite.Self-scan
codeguard(full + diff vsmain),validate,doctor, andmake checkall pass on this branch: 0 fail findings.Knowledge captured
.claude/knowledge/architecture-boundaries.mdupdated with: diff-vs-full is centralized inFinalizeSection; TS/JS bypassfindingsForFile(repo-wide rules need a separate pass); the literal-gate perf insight and gate-superset invariant; theScanTargetFilesper-section cache-key gotcha; and the history package layering (must be top-level to avoid an import cycle).🤖 Generated with Claude Code