-
Notifications
You must be signed in to change notification settings - Fork 0
Pre commit
Run sbom scan on every commit that touches a lockfile, and refuse the
commit when a finding reaches the severity you set. The hook lives in this
repository, so rev: is a CLI release tag: the hook and the binary it runs
cannot disagree.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/mlab-sh/mlab-cli
rev: v1.1.1
hooks:
- id: mlab-sbom-scanpre-commit installNothing else. No key is needed: vuln.mlab.sh is public (see Hosts).
| Hook | Where mlab comes from |
First run |
|---|---|---|
mlab-sbom-scan |
pre-commit builds it from this repository at rev
|
~2 minutes, then cached |
mlab-sbom-scan-system |
the mlab already on your PATH
|
instant |
mlab-sbom-scan needs nothing installed beforehand: pre-commit uses your
cargo if there is one, and bootstraps a Rust toolchain into its own cache if
not. The build is slow once because the release profile uses full LTO.
mlab-sbom-scan-system is for machines that already have the CLI from
Homebrew or a package. The version is then whatever you installed,
not rev.
Only when a staged file matches one of these names, in any directory:
| Ecosystem | Files |
|---|---|
| npm |
package-lock.json, npm-shrinkwrap.json
|
| crates.io | Cargo.lock |
| Packagist | composer.lock |
| RubyGems | Gemfile.lock |
| Go | go.sum |
| CycloneDX |
bom.json, *.cdx.json
|
A commit that touches none of them skips the hook entirely: no process, no
request. When several match, they go to one mlab sbom scan invocation and
--fail-on is judged once across all of them, so one bad lockfile never hides
what the others found.
The pattern names only what the server parses correctly. Matching a file it
cannot read would block the commit on exit 4, or pass it on a wrong parse:
-
poetry.lockanduv.lockare currently read asCargo.lock, so every Python package is looked up on crates.io and comes back clean. Left out until that is fixed server-side. -
yarn.lock,pnpm-lock.yaml,Pipfile.lockandmise.lockare not parsed yet. -
requirements*.txtis parsed only when every line is pinned with==. A file of ranges fails with "no dependencies parsed". If yours are fully pinned, opt in:
- id: mlab-sbom-scan
files: '(^|/)(Cargo\.lock|package-lock\.json|requirements[^/]*\.txt)$'The default is --fail-on high. Override it with args:
- id: mlab-sbom-scan
args: [--fail-on, critical]critical, high, medium or low, scored from the CVSS v3 vector exactly as
the web UI does. An advisory without a vector (an "unmaintained" notice, say) shows
as unknown and does not trip --fail-on high.
| Exit | Meaning | What to do |
|---|---|---|
0 |
Nothing at or above the threshold | — |
7 |
A finding reached the threshold | Upgrade to the Fixed in version |
3 |
Rate limited | Wait a few seconds and commit again, or set a vuln token |
1 |
Network failure | See below |
| other | See Exit codes |
An incomplete scan never passes: if a package could not be scanned or an advisory source is down, the hook fails with the reason rather than letting the commit through looking clean. The same holds offline. When you have to commit anyway, skip the hook for that one commit:
git commit --no-verifyThat is the point of a pre-commit hook being a local guard rather than a control: the gate that cannot be skipped is the same command in CI.
- run: mlab sbom scan package-lock.json --fail-on highWithout a token the scan quota is counted per IP. Set MLAB_VULN_TOKEN in your
shell profile to get your own, which matters when many developers commit from
behind one office NAT:
export MLAB_VULN_TOKEN=...See Authentication. Never put the token in
.pre-commit-config.yaml: that file is committed.
A tag can be moved. To pin the exact commit behind it, let pre-commit rewrite
rev to a SHA with the tag as a comment:
pre-commit autoupdate --freezepre-commit try-repo https://github.com/mlab-sh/mlab-cli mlab-sbom-scan --all-files