chore(hooks): add gitleaks secret scan to pre-commit #317

Merged
allan merged 5 commits from chore/gitleaks-precommit into fix/viya-test-suite-and-refreshcatalog-json 2026-09-14 12:15:39 +00:00
Collaborator

Adds a gitleaks secret scan to the pre-commit hook, before prettier runs, and repairs the pre-existing large-commit check.

What changed

  • .git-hooks/pre-commit: runs gitleaks protect --staged --redact on staged changes before the prettier check. Exits 1 with guidance when a potential secret is found, pointing at .gitleaksignore for false positives.
  • package.json / package-lock.json: adds @nogoo9/gitleaks (8.30.1-post.2) as a root devDependency. It ships the official gitleaks v8.30.1 binaries as platform-scoped optionalDependencies (esbuild-style) - no postinstall scripts, no install-time network calls - so it installs cleanly under the repo's ignore-scripts=true.
  • Hard requirement: the hook uses only the repo-pinned node_modules/.bin/gitleaks - no system-binary fallback, no soft skip. A fresh clone without npm i is blocked with a hint until the binary is installed, so no clone silently skips the secrets scan.
  • .git-hooks/pre-commit (follow-up commit): the pre-existing size check was dead code (both prettier branches exit first) and had three defects of its own - the blocking exit 1 was inside a ( ... ) subshell, the 2**20 arithmetic errors under dash, and it measured HEAD^..HEAD (the previous commit) instead of the content being committed. It now sums the new blob sizes the commit would introduce via git diff --cached --raw, keeps the 2MB threshold and the --no-verify escape hatch, and runs before prettier so it always executes.

Why this wrapper

  • Zero runtime dependencies; the platform binary (verified: linux-x64 is byte-identical to the official v8.30.1 release tarball) is installed by npm's optionalDependencies mechanism only for the matching os/cpu.
  • A gitleaks bin is exposed on node_modules/.bin (as well as npx gitleaks), pinned by package-lock.json.

Verification

  • Full-repo scan (gitleaks dir .) with the default config: no leaks found.
  • Staged-secret test: a realistic AWS key + private key staged in a scratch repo -> leaks found: 2, hook exits 1.
  • Clean staged change -> passes through to the size check then prettier.
  • Missing binary: hook blocks with 'run npm i' and exit 1.
  • Size check: staged 3MB blob -> blocked with exit 1; mode-only change -> 0 new bytes, passes; small change -> passes.
  • npm audit --omit=dev: 0 vulnerabilities (the 5 dev-only advisories are in the pre-existing vendored node_modules/npm package, unrelated to this change).
Adds a gitleaks secret scan to the pre-commit hook, before prettier runs, and repairs the pre-existing large-commit check. ## What changed - **`.git-hooks/pre-commit`**: runs `gitleaks protect --staged --redact` on staged changes before the prettier check. Exits 1 with guidance when a potential secret is found, pointing at `.gitleaksignore` for false positives. - **`package.json` / `package-lock.json`**: adds `@nogoo9/gitleaks` (8.30.1-post.2) as a root devDependency. It ships the official gitleaks v8.30.1 binaries as platform-scoped optionalDependencies (esbuild-style) - **no postinstall scripts, no install-time network calls** - so it installs cleanly under the repo's `ignore-scripts=true`. - **Hard requirement**: the hook uses only the repo-pinned `node_modules/.bin/gitleaks` - no system-binary fallback, no soft skip. A fresh clone without `npm i` is blocked with a hint until the binary is installed, so no clone silently skips the secrets scan. - **`.git-hooks/pre-commit`** (follow-up commit): the pre-existing size check was dead code (both prettier branches exit first) and had three defects of its own - the blocking `exit 1` was inside a `( ... )` subshell, the `2**20` arithmetic errors under dash, and it measured `HEAD^..HEAD` (the previous commit) instead of the content being committed. It now sums the new blob sizes the commit would introduce via `git diff --cached --raw`, keeps the 2MB threshold and the `--no-verify` escape hatch, and runs before prettier so it always executes. ## Why this wrapper - Zero runtime dependencies; the platform binary (verified: linux-x64 is byte-identical to the official v8.30.1 release tarball) is installed by npm's optionalDependencies mechanism only for the matching os/cpu. - A `gitleaks` bin is exposed on `node_modules/.bin` (as well as `npx gitleaks`), pinned by package-lock.json. ## Verification - Full-repo scan (`gitleaks dir .`) with the default config: **no leaks found**. - Staged-secret test: a realistic AWS key + private key staged in a scratch repo -> `leaks found: 2`, hook exits 1. - Clean staged change -> passes through to the size check then prettier. - Missing binary: hook blocks with 'run npm i' and exit 1. - Size check: staged 3MB blob -> blocked with exit 1; mode-only change -> 0 new bytes, passes; small change -> passes. - `npm audit --omit=dev`: 0 vulnerabilities (the 5 dev-only advisories are in the pre-existing vendored `node_modules/npm` package, unrelated to this change).
hermes added 1 commit 2026-09-10 22:37:05 +00:00
chore(hooks): add gitleaks secret scan to pre-commit
Build / Build-and-ng-test (pull_request) Failing after 1m45s
Build / Build-and-test-development (pull_request) Skipped
Lighthouse Checks / lighthouse (pull_request) Successful in 20m14s
b3b9755aa7
Run 'gitleaks protect --staged' before prettier in the pre-commit hook.
The gitleaks binary comes from the @nogoo9/gitleaks devDependency,
which ships official binaries as platform optionalDependencies - no
postinstall scripts, so it installs under ignore-scripts=true.
Falls back to a system gitleaks, and soft-skips with a hint to run
'npm i' on a fresh clone rather than blocking the commit.
hermes added 1 commit 2026-09-10 23:03:52 +00:00
fix(hooks): make the pre-commit size check actually run
Build / Build-and-ng-test (pull_request) Failing after 1m47s
Build / Build-and-test-development (pull_request) Skipped
Lighthouse Checks / lighthouse (pull_request) Successful in 20m51s
53838036e6
The size check sat after the prettier block, whose branches both exit,
so it was unreachable - and it had three further defects: the exit 1
lived inside a ( ... ) subshell so it could never block the commit,
the 2**20 arithmetic errors under /bin/sh (dash) leaving size_limit
unset, and it measured HEAD^..HEAD (the previous commit) rather than
the content being committed, which does not exist yet in pre-commit.

Rewrite it to sum the sizes of the new blobs the commit would
introduce (git diff --cached --raw, new blob ids -> cat-file
--batch-check), keep the 2MB threshold and the documented --no-verify
escape hatch, and move it before the prettier check so it always runs.

Verified with a staged 3MB blob (blocked, exit 1), a small staged
change (passes through to prettier), and a mode-only change (no new
blob, passes).
hermes added 1 commit 2026-09-10 23:06:37 +00:00
fix(hooks): require the repo-pinned gitleaks, drop the fallbacks
Build / Build-and-ng-test (pull_request) Failing after 1m46s
Build / Build-and-test-development (pull_request) Skipped
Lighthouse Checks / lighthouse (pull_request) Successful in 21m12s
fbcde41321
A soft skip (and the system-gitleaks fallback) let a clone without
node_modules commit with no secrets scan at all, so the hook would
never force the install. The hook now hard-blocks with a hint to run
'npm i' until the @nogoo9/gitleaks binary is present in
node_modules/.bin.

Verified with the binary present (scan runs and passes) and absent
(blocked, exit 1).
hermes left a comment
Author
Collaborator

Reviewed the diff (gitleaks pre-commit hook, @nogoo9/gitleaks devDependency, lockfile, commit-size rewrite) plus hook wiring and CI state at head fbcde413.

  • .gitea/workflows/build.yaml - CI is red on this head: Build-and-ng-test failed at the Check audit step (adm-zip 0.6.0 via @sasjs/cli 4.20.1 in sas/package-lock.json, GHSA-vwc7-r8mq-g2x9, moderate, inherited from base #316). Fix the audit before merge - bump @sasjs/cli once cli #1467 lands or add an override; do not merge around a failing gate.

  • package.json:26 - the "prepare" script ("git rev-parse --git-dir && git config core.hooksPath ./.git-hooks && git config core.autocrlf false || true") never runs because .npmrc sets ignore-scripts=true. Verified empirically: with ignore-scripts=true, npm install leaves core.hooksPath unset; with it off, prepare wires the hook path. Fresh clones therefore never activate .git-hooks/pre-commit, so the new gitleaks gate is silently inactive for them, contradicting the hook comment "no clone silently skips the secrets scan". Add a one-time "git config core.hooksPath ./.git-hooks" step to CONTRIBUTING.md, or wire the hook without relying on lifecycle scripts.

2 findings above for review.

Reviewed the diff (gitleaks pre-commit hook, @nogoo9/gitleaks devDependency, lockfile, commit-size rewrite) plus hook wiring and CI state at head fbcde413. - .gitea/workflows/build.yaml - CI is red on this head: Build-and-ng-test failed at the Check audit step (adm-zip 0.6.0 via @sasjs/cli 4.20.1 in sas/package-lock.json, GHSA-vwc7-r8mq-g2x9, moderate, inherited from base #316). Fix the audit before merge - bump @sasjs/cli once cli #1467 lands or add an override; do not merge around a failing gate. - package.json:26 - the "prepare" script ("git rev-parse --git-dir && git config core.hooksPath ./.git-hooks && git config core.autocrlf false || true") never runs because .npmrc sets ignore-scripts=true. Verified empirically: with ignore-scripts=true, npm install leaves core.hooksPath unset; with it off, prepare wires the hook path. Fresh clones therefore never activate .git-hooks/pre-commit, so the new gitleaks gate is silently inactive for them, contradicting the hook comment "no clone silently skips the secrets scan". Add a one-time "git config core.hooksPath ./.git-hooks" step to CONTRIBUTING.md, or wire the hook without relying on lifecycle scripts. 2 findings above for review.
hermes added 2 commits 2026-09-14 11:44:26 +00:00
Clears the moderate adm-zip advisory (GHSA-vwc7-r8mq-g2x9) from the sas npm audit gate - @sasjs/cli 4.20.3 replaces adm-zip with yauzl/yazl.
docs(contributing): document one-time git hook activation
Build / Build-and-ng-test (pull_request) Successful in 5m21s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m1s
Build / Build-and-test-development (pull_request) Successful in 24m44s
8418e0cb1d
allan merged commit ca19dbaefb into fix/viya-test-suite-and-refreshcatalog-json 2026-09-14 12:15:39 +00:00
allan deleted branch chore/gitleaks-precommit 2026-09-14 12:15:39 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dc/dc#317