feat(code-scanner): add the secrets subsystem (PRD 0003) - #50
Merged
Conversation
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
| return allow.some((entry) => { | ||
| if (entry.startsWith('sha256:')) return finding.fingerprint === entry; | ||
| if (entry.includes('*')) { | ||
| const inner = entry.replace(/^\*+/, '').replace(/\*+$/, ''); |
|
|
||
| let buffer: Buffer; | ||
| try { | ||
| buffer = await readFile(file); |
| * can be found and argued with instead of being invisible. | ||
| */ | ||
| export function isKnownNonSecret(value: string): string | null { | ||
| if (PLACEHOLDER.test(value)) return 'placeholder-or-example'; |
Implements PRD 0003. gitleaks in CI already covers the commit path; this
covers what reaches a server without passing through a commit — a hand-written
.env, a config.json.bak in a web root, credentials baked into a gitignored
dist/.
Two defaults deliberately invert what a repository scanner does:
- gitignored files are scanned and labelled, not skipped. They are the
likeliest place for a real credential and the least likely to have been
looked at, precisely because every repo-oriented tool ignores them.
- high-risk filenames (.env, id_rsa, *.pem, .npmrc) are scanned even when
the size and binary rules would skip them.
Precision is the feature, because a scanner that reports 200 findings on first
run gets switched off and then detects nothing:
- structured rules over entropy; entropy only fires when the value is
assigned to a secret-shaped name, never on randomness alone
- GitHub tokens are CRC-verified, so a lookalike is not reported as a leak
- known non-secrets are suppressed by NAMED rule (git-sha1, uuid,
lockfile-integrity, placeholder-or-example...) so a wrong suppression can
be argued with rather than being invisible tuning
- overlapping rules collapse to one finding per secret
Redaction is structural, not configurable: findings carry a masked preview and
a sha256 fingerprint, and there is no code path from a raw value to an event,
alert or log. A test asserts this rather than trusting it.
On the fixtures: GitHub push protection rejected the first version of this
branch, flagging a Slack token and a Stripe key in the test file — a real
secret scanner catching the fixtures of a secret scanner. Rather than
allowlist a secret pattern on the repository, which is the habit this module
exists to discourage, fixtures are assembled at runtime from fragments so no
matchable literal is committed. The four that cannot be assembled away (a PEM
header, a knowingly-invalid checksum, two entropy strings) carry an inline
gitleaks:allow on the line it excuses. Kept as a single commit because
gitleaks scans history, so an intermediate commit with an un-annotated fixture
fails CI even when the final tree is clean.
66 tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ralyodio
force-pushed
the
feat/code-scanner-secrets
branch
from
July 28, 2026 16:53
41f5ff0 to
99f3d86
Compare
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.
Implements PRD 0003 — the
secrets/subsystem ofcode-scanner.Why, given gitleaks already runs in CI
gitleakscovers the commit path. This covers everything that reaches a server without passing through a commit, which a repository scanner structurally cannot see:.envwritten by hand during a 2am fix and never removedconfig.json.bakordump.sqlleft in a web rootdist/Two deliberate inversions
.env*,id_rsa,*.pem,.npmrc) are scanned even when the size/binary rules would skip them. A 6 MB.envis still a.env.Precision is the feature
A scanner that reports 200 findings on first run gets switched off, and a switched-off scanner has zero recall. So:
git-sha1,uuid,lockfile-integrity,placeholder-or-example… each is a named rule, so a wrong suppression can be argued with rather than being invisible tuning.Redaction is structural, not configurable
Findings carry a masked preview (
AKIA***********12345) and asha256:fingerprint. There is no code path from a raw value to an event, alert body or log line, and no setting that changes it. A test asserts the raw value appears nowhere in serialized output.A note on the test fixtures
The first push of this branch was rejected by GitHub push protection: it flagged a Slack token and a Stripe test key in the test file. A real secret scanner caught the test fixtures of a secret scanner.
The two options were to allowlist the pattern on the repository, or to stop committing strings that look like credentials. Allowlisting a secret pattern in a security repo to make a push succeed is exactly the habit this module exists to discourage — so fixtures are now assembled at runtime from fragments. The values under test are byte-identical; there is simply no matchable literal in the committed file.
Verification
.env, correctly ignored a UUID and AWS's own documentation keyAKIAIOSFODNN7EXAMPLE.