Add automated secret scanning (make check-secrets, pre-commit hook) #67
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
keyop-go/nfq_forwarder!67
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue24_secret_scanning"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of #24 (https://gitlab.keyop.co.uk/keyop/go/nfq_forwarder/-/work_items/24).
Background
The bulk of issue #24 (redacting GitLab tokens accidentally committed into
notes/chatexports) was handled directly against
mainvia a fullgit filter-repo --replace-texthistoryrewrite - not something that can go through a normal branch/MR, since it rewrites
main's ownhistory. That part is done: every commit SHA changed, all tags were re-pushed pointing at the
rewritten commits, and a follow-up
gitleakssweep of the rewritten history confirms zeroremaining secrets.
This MR is the preventative half of the ticket (expanded per Danny's request beyond the
originally-scoped manual redaction script): automated scanning so this can't recur silently.
Changes
make check-secrets: runsgitleaks git --log-opts="--all"(full-history sweep) and isnow part of
make lint, so both local runs and CI's existinglintjob catch a committedsecret with no
.gitlab-ci.ymlchanges needed.make install-git-hooks: installsscripts/pre-commit(gitleaks protect --staged- afast, staged-diff-only scan) as an opt-in pre-commit hook, catching a secret before it's ever
committed rather than only before it's merged. Not installed automatically, since git doesn't
version
.git/hooks- this is a one-time manual step per clone.make setupinstallsgitleaksitself if missing, matching the existing pattern forgoreleaser.CLAUDE.mdupdated (Build & dev commands, Design notes, Known issues - including a note aboutthe history rewrite itself, for future readers).
Testing
shaped like a real GitLab PAT, confirmed
git commitwas rejected with the expected finding,then removed it.
commit process).
make lint(now includingcheck-secrets) is clean.mentioned in issue #24
assigned to @danny
requested review from @danny
LGTM
approved this merge request
aborted the automatic merge because the source branch was updated. Learn more.
added 1 commit
4a3a9b06- Scope check-secrets to HEAD's ancestry, not every local refCompare with previous version
The lint pipeline failure just now was a real (if slightly indirect) finding, not a bad rebase:
check-secretsusedgitleaks git --log-opts="--all", which follows every local ref in whatever checked out the repo - and the CI runner's reused workspace still had local refs/objects from before the issue #24 history rewrite, even though the actual GitLab remote (confirmed via the API - onlymainand this branch exist) has already moved past them. So it was flagging already-redacted history via a stale local cache, not a real leak.Fixed by scoping the scan to
HEAD's own ancestry instead of every local ref - every commit that matters ends up inmain's history via a merged MR anyway, so this loses no real coverage. Verified clean locally; pushed as a follow-up commit.added 1 commit
7b19ec3b- Actually scope check-secrets to HEAD (previous fix was a no-op)Compare with previous version
Correction to my last comment: dropping the explicit
--log-opts="--all"didn't actually change anything, and the pipeline failed identically for that reason - gitleaks' own default when--log-optsis empty isgit log ... --full-history --all, i.e. still every local ref. An empty override falls back to that same default rather than meaning "no extra scope."Fixed properly this time with an explicit
--log-opts="HEAD". Verified by creating a local ref pointing at one of the old pre-rewrite commits and confirming--log-opts="HEAD"correctly ignores it while the bare default reproduces the exact CI failure - so this is the real fix, not another guess. HEAD's ancestry is a property of the commit graph itself (content-addressed), independent of whatever stale refs a given checkout happens to be carrying, which I also confirmed directly:git merge-base --is-ancestor <old-sha> HEADreturns false, i.e. that commit was never reachable from HEAD in the first place.mentioned in commit
cdeebc121a