Repository navigation
Conversation
Add a top-level .pre-commit-hooks.yaml exposing `vet-scan` (build from source via the Go toolchain) and `vet-scan-system` (use an installed vet binary) so downstream repositories can run `vet scan` at the git commit boundary via the pre-commit framework. Both hooks run `vet scan -D .` with pass_filenames disabled and are scoped via a files regex to dependency manifests and lockfiles across npm, PyPI, Maven, Go, Ruby, Rust and PHP, so they stay quiet on commits that do not change dependencies. Default behavior is report-only; teams opt into blocking via a CEL --filter ... --filter-fail. Document usage in the README under Production Ready Integrations. Closes safedep#443 Signed-off-by: Devam Shah <devamshah91@gmail.com>
SafeDep Report SummaryNo dependency changes detected. Nothing to scan. This report is generated by SafeDep Github App |
|
@abhisek do we need it? |
|
@KunalSin9h No. I think this is more of a docs thing and not part of |
|
Agreed, it's a docs thing. A hook is integration guidance, not something the binary's repo should carry. Concrete home, if it's useful: I'd frame the page as defense-in-depth rather than a primary control: by pre-commit time the package is already on the machine, which is exactly the point you made on #443. PMG is the install-time answer; the hook is just local parity with the CI policy gate for teams that want the same verdict before a push. Happy to send that docs PR if you want it. Should #443 stay open to track the docs page, or be closed now that PMG covers the install-time case? |
|
Following up here — rather than leave this as a proposal, I can just open the docs PR against safedep/docs so there's a concrete diff to merge or close on sight. It'd be the one |
Summary
Adds a top-level
.pre-commit-hooks.yamlexposing avet-scanhook so downstream repositories can shift dependency vetting left and catch malicious or vulnerable packages locally, before they are committed.Problem / motivation
vetalready guards the PR boundary viavet-action(GitHub) and the GitLab CI component, but there is no first-class way to run it at thegit commitboundary on a developer's machine (#443). The earlier the signal, the cheaper the fix: a malicious or slop-squatted dependency that reaches CI has already been committed and pushed, and a compromised lockfile that lands onmainwidens the blast radius. The pre-commit framework is the de-facto standard for local Git hooks, but consumingvetthrough it today requires every team to hand-roll alocalhook. Shipping a maintained manifest in this repo makes adoption a two-line.pre-commit-config.yamlchange.Change
.pre-commit-hooks.yamlat the repository root with two hooks:vet-scan—language: golang, buildsvetfrom source via the Go toolchain so no prior installation is required (mirrors how gitleaks/golangci-lint ship their own hooks).vet-scan-system—language: system, reuses an already-installedvet(Homebrew/npm/release binary) for a faster path.vet scan -D .withpass_filenames: false(vet scans the directory tree, not a file list) andrequire_serial: true.files:regex scopes execution to dependency manifests and lockfiles across the ecosystemsvetsupports (npm, PyPI, Maven, Go, Ruby, Rust, PHP). The hook therefore stays quiet on ordinary commits and only fires when dependencies actually change — keeping developer friction and false positives low.--filter ... --filter-fail.Default behavior is report-only so the hook never surprises a developer by blocking a commit; teams opt into hard-fail with an explicit policy filter.
Security rationale
This pulls software-supply-chain enforcement to the earliest practical control point in the SDLC.
vet scanqueries known-malicious package intelligence by default (--malware-queryis on), so typosquatted / slop-squatted dependencies are flagged at commit time rather than after distribution.vulns.critical.exists(p, true)), aligning with OWASP Top 10 A06:2021 — Vulnerable and Outdated Components.golanghook keeps the toolchain pinned to therevthe consumer selects, avoiding an unpinned download in the developer's hook path.The hook narrows the exposure window described in #443: a flagged dependency is surfaced before the working tree change becomes a commit, reducing the likelihood of incident-response on a developer machine.
Testing / validation
Validated locally with
pre-commit4.6.0 and Go 1.26.2 (matches the repo'sgo 1.26.2):pre-commit validate-manifest .pre-commit-hooks.yaml→ exit 0 (manifest conforms to the pre-commit schema).pre-commit try-repo <repo> vet-scan --all-filesagainst a sample consumer repo containing ago.mod→ thegolanghook compiledvetfrom source, ranvet scan -D ., scanned the discovered manifest, queried malware intelligence, and reportedvet scan (build from source) ... Passed.files:regex unit-checked in Pythonre(the engine pre-commit uses): asserted positive matches forpackage-lock.json,app/go.mod,src/requirements-dev.txt,poetry.lock,Cargo.toml,frontend/yarn.lock,pom.xml,composer.lock,Pipfile,pnpm-lock.yaml, and negative matches forREADME.md,main.go,src/index.ts,config.yaml,LICENSE,go.work— confirming the hook does not fire on non-dependency files.No live external target or API key is required:
vet scan -D .resolves manifests and queries known-malicious package data with default flags.Notes for maintainers
rev: v1.x.xin the README/manifest comments is a placeholder; consumers pin to a released tag.files:filter; it does not implement true per-file incremental/cached scanning (avetCLI concern, out of scope for a hook manifest).Closes #443