mlab docs

GitHub Action

Scan your lockfiles for known CVEs on every push or pull request with the official vuln.mlab.sh SBOM scan GitHub Action.

The official mlab-sh/vuln-scan-action scans your lockfiles for known CVEs on every push or pull request, powered by vuln.mlab.sh. It auto-detects lockfiles, checks every dependency against OSV + Sonatype OSS Index, writes a job summary, and fails the build (or just reports) based on a severity threshold.

No dependency install, no local database. Parsing and scanning happen server-side: the Action uploads your lockfile and reports the result.

Quick start

name: SBOM scan
on: [push, pull_request]

jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: mlab-sh/vuln-scan-action@v1
        with:
          fail-on: high
          token: ${{ secrets.VULN_MLAB_TOKEN }}

With no inputs, it auto-detects common lockfiles in the repo and fails on any known vulnerability.

Why a token

Anonymous scans are rate-limited to 8/hour per IP, and GitHub-hosted runners share egress IPs across many repos, so anonymous CI is unreliable. A personal API token gets you a dedicated 25 scans/hour.

Sign in at vuln.mlab.sh/me/tokens and generate a token.

Add it as a repository secret named VULN_MLAB_TOKEN.

Pass it via the token: input (as shown above).

Inputs

InputDefaultDescription
path(auto-detect)Lockfile(s) to scan, newline- or comma-separated.
working-directory.Base directory for auto-detection.
formatautoForce the parser: npm, cargo, pip, composer, gem, go, cyclonedx, mise.
fail-onanyMinimum severity that fails the build: any, critical, high, medium, low, none.
soft-failfalseIf true, never fail the build. Report findings and set outputs only.
token(none)vuln.mlab.sh API token. Strongly recommended for CI.
api-urlhttps://vuln.mlab.sh/api/v2/scanOverride the scan endpoint.

Auto-detected lockfiles: Cargo.lock, package-lock.json, npm-shrinkwrap.json, composer.lock, Gemfile.lock, go.sum, requirements.txt, mise.lock. (node_modules, vendor, target, and similar are skipped.)

Outputs

OutputDescription
totalTotal vulnerabilities found across all lockfiles.
vulnerable-packagesNumber of distinct vulnerable packages.
failedtrue if the fail-on threshold was met (regardless of soft-fail).

Examples

Report only (never fail), gate on the output yourself:

- id: scan
  uses: mlab-sh/vuln-scan-action@v1
  with:
    soft-fail: "true"
    token: ${{ secrets.VULN_MLAB_TOKEN }}
- run: echo "Found ${{ steps.scan.outputs.total }} vulnerabilities"

Only fail on critical, scan a specific file:

- uses: mlab-sh/vuln-scan-action@v1
  with:
    path: server/Cargo.lock
    fail-on: critical
    token: ${{ secrets.VULN_MLAB_TOKEN }}

Monorepo, scan several lockfiles:

- uses: mlab-sh/vuln-scan-action@v1
  with:
    path: |
      frontend/package-lock.json
      backend/go.sum
      infra/requirements.txt
    token: ${{ secrets.VULN_MLAB_TOKEN }}

How it works

Each lockfile is POSTed to /api/v2/scan. The service parses it, resolves every dependency's known vulnerabilities, and returns one result per package. The Action then normalizes each finding's severity, applies your fail-on threshold, annotates the worst offenders inline (errors for high/critical, warnings otherwise), writes a summary table to the job summary, and sets the total / vulnerable-packages / failed outputs.

Notes

  • Coordinates the scanner could not resolve (upstream outage) are surfaced as warnings and not counted as clean. They never silently pass a gate.
  • Manifests over 512 packages are scanned up to that ceiling (a warning is emitted). Split very large monorepos across multiple lockfile paths.
  • When scanning multiple lockfiles the Action spaces requests about 1s apart to stay within the per-token rate limit.

See also

On this page