osv-scanner
Configures and runs Google OSV-Scanner - open-source SCA against the OSV.dev vulnerability database; supports `osv-scanner scan -r ./` recursive scan + per-lockfile scan via `-L package-lock.json`; SBOM input (CycloneDX / SPDX) for non-standard package managers; `--format json|sarif|markdown|vertical|html` output; suppressions via `osv-scanner.toml` config. Use when the team needs OSS-native SCA without commercial-license overhead, or wants a second-opinion DB pair with Snyk's commercial DB.
Install with skills.sh (any agent)
npx skills add testland/qa --skill osv-scannerosv-scanner
When to use
Step 1 - Install
Per osv-usage (opens in new window):
docker pull ghcr.io/google/osv-scanner:latestOther install paths (consult google.github.io/osv-scanner for current options per platform):
# Go install
go install github.com/google/osv-scanner/cmd/osv-scanner@v1
# Homebrew
brew install osv-scanner
# Direct binary download from github.com/google/osv-scanner/releasesStep 2 - Basic recursive scan
Per osv-usage (opens in new window):
osv-scanner scan -r ./my-project-dir/Auto-detects manifest files (package-lock.json, Pipfile.lock, go.mod, Cargo.lock, etc.) and queries OSV.dev for each.
Per-lockfile scan (-L targets one lockfile without recursing, useful in monorepos):
osv-scanner scan -L package-lock.json --output-file scan-results.txtStep 3 - Output formats
Per osv-usage (opens in new window): --format json and --format=vertical and --format=html are referenced. Full format list per the osv-scanner documentation:
| Format | Use |
|---|---|
--format json | For downstream aggregation |
--format sarif | GitHub Code Scanning upload |
--format markdown | PR comments |
--format vertical | Default human-readable |
--format html | Standalone report |
Step 4 - SBOM-driven scanning
For projects with custom build systems that emit SBOMs but lack natively-parsed lockfiles:
osv-scanner scan --sbom my-app.cyclonedx.json
osv-scanner scan --sbom my-app.spdx.jsonThis composes with syft-generation in the qa-sbom plugin - Syft generates the SBOM, OSV-Scanner queries OSV.dev against it.
Step 5 - osv-scanner.toml config
Suppress a vuln with an expiring, reasoned entry (auditable in git):
# osv-scanner.toml
[[IgnoredVulns]]
id = "CVE-2024-1234"
ignoreUntil = 2026-12-15T00:00:00Z
reason = "Reachability confirms unreachable; tracked in JIRA-1234"The full schema ([[PackageOverrides]], multi-entry config, --config flag, the mandatory justification template) is in references/osv-scanner-config-and-ci.md.
Step 6 - False-positive triage (MANDATORY)
Suppress via [[IgnoredVulns]] (per-CVE, with ignoreUntil) or [[PackageOverrides]] (per pinned package + ecosystem) in osv-scanner.toml; --severity-threshold is a scan-time filter, not a suppression. Every entry carries a mandatory reason + approver + re-review date. ignoreUntil is enforced - past-due ignores re-surface in the scan results. The suppression-layer table and justification template are in references/osv-scanner-config-and-ci.md.
Step 7 - Exit codes + CI gating
OSV-Scanner exit codes (verify against current docs):
The google/osv-scanner-action GHA (Docker invocation + SARIF upload) is in references/osv-scanner-config-and-ci.md.
Step 8 - License-checking (adjacent feature)
OSV-Scanner has experimental license-summary support:
osv-scanner --experimental-licenses-summary scan -r .For full license-compliance + scanning, pair with spdx-format (in the qa-sbom plugin) or use a dedicated tool like ScanCode / FOSSology.
Anti-patterns
Limitations
References
osv-scanner config, triage, and CI
View source (opens in new window)osv-scanner config, triage, and CI
Deep reference for the osv-scanner SKILL.md. SKILL.md keeps install, the recursive/per-lockfile scan, output formats, SBOM input, exit codes, and a minimal ignore snippet; this file holds the full osv-scanner.toml schema, the justification template, and the GitHub Actions workflow.
Full osv-scanner.toml schema
Point the scanner at a config with --config (osv-usage (opens in new window)):
osv-scanner --config ./my-osv-scanner-config.toml scan -r .# osv-scanner.toml
[[IgnoredVulns]]
id = "CVE-2024-1234"
ignoreUntil = 2026-12-15T00:00:00Z
reason = "Reachability analysis confirms unreachable; tracked in JIRA-1234"
[[IgnoredVulns]]
id = "GHSA-xxxx-yyyy-zzzz"
ignoreUntil = 2026-09-30T00:00:00Z
reason = "Vendor-supplied; pin to current version pending Q3 upgrade"
[[PackageOverrides]]
name = "lodash"
version = "4.17.20"
ecosystem = "npm"
ignore = true # Suppress all vulns in this exact pinned version
reason = "Test fixture; not in production dependency graph"Suppression layers and justification
Three suppression layers:
| Mechanism | Where | Use |
|---|---|---|
[[IgnoredVulns]] in osv-scanner.toml (with ignoreUntil) | Repo root | Per-CVE; auditable in git |
[[PackageOverrides]] in osv-scanner.toml | Repo root | Per-package version + ecosystem |
--severity-threshold filter (when supported by version) | CI flag | Scan-time filter, not suppression |
Justification is mandatory in osv-scanner.toml:
[[IgnoredVulns]]
id = "CVE-2024-1234"
ignoreUntil = 2026-12-15T00:00:00Z
reason = """
Reachability: function `vulnerable_func` not exported; verified via
git grep + dynamic instrumentation. Issue requires admin context
which is separately controlled.
Approved-by: alice@example.com
Re-review-date: 2026-09-15
"""ignoreUntil is enforced by osv-scanner - past-due ignores are re-surfaced in the scan results. Cadence: every quarter, list all [[IgnoredVulns]] entries + re-validate the reason; expired ones removed, persistent ones escalated to upgrade work.
GitHub Actions CI
The google/osv-scanner-action GHA wraps the Docker invocation + SARIF upload:
jobs:
osv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: google/osv-scanner-action/osv-scanner-action@v1
with:
scan-args: |-
--recursive
--skip-git
--format=sarif
--output=osv.sarif
./
- uses: github/codeql-action/upload-sarif@v3
if: always()
with: { sarif_file: osv.sarif }Related skills
bundle-audit-ruby
Use when a Ruby project has a Gemfile.lock and needs CVE/GHSA scanning or a CI SCA gate. Installs and runs bundler-audit against a Ruby Gemfile.lock, updating the ruby-advisory-db corpus, scanning for vulnerable gem versions and insecure sources, suppressing false positives via .bundler-audit.yml, and gating CI on non-zero exit. Ruby-only SCA scanner: for other ecosystems use npm-pip-maven-audit (multi-ecosystem dispatcher), snyk-test, or osv-scanner; cargo-audit-rust is the Rust analog; once findings exist, reachability-analyzer downranks unreachable gems - not this.
cargo-audit-rust
Configures and runs cargo-audit against the RustSec Advisory Database for Rust projects; covers `cargo audit` (vulnerability scan), `cargo audit fix` (automated dependency updates), `--deny unmaintained|unsound|yanked|warnings` exit-code control, `audit.toml` per-advisory suppression with mandatory `expires` + `reason`, SARIF output for GitHub Code Scanning upload, and `rustsec/audit-check` GitHub Actions integration. Use when the codebase has a Cargo.lock and needs Rust-specific SCA beyond what the multi-ecosystem npm-pip-maven-audit wrapper provides.
cve-exploitability-triage
Ranks known CVE findings by real-world exploitability instead of severity alone: enriches each CVE with its EPSS probability (the chance exploitation activity is observed in the next 30 days) and CISA KEV membership (confirmed exploited in the wild), applies OpenVEX status assertions to set aside vulnerabilities the product is not affected by, applies a reachability heuristic for vulnerable code that is never called, and assigns every finding to one of four buckets (Fix-Now, Fix-This-Sprint, Fix-Backlog, Accept-Risk) using documented EPSS thresholds. Treats a CISA KEV listing as non-waivable under any justification. Use when a dependency, container image, or SBOM vulnerability scan has produced more CVEs than the team can fix in the available window and someone has to decide which ones get fixed first and which can wait.
dependabot-config
Reference for `.github/dependabot.yml` - GitHub-native dependency-update orchestrator. Required keys (`version: 2`, `updates[]` array) plus per-update fields (`package-ecosystem`, `directory` / `directories`, `schedule.interval`); common optional fields (`ignore`, `groups`, `allow`, `labels`, `milestone`, `open-pull-requests-limit`, `target-branch`, `vendor`, `versioning-strategy`, `assignees`, `commit-message`); auto-rebase + grouped-PR + security-only updates. Use when authoring or reviewing Dependabot configs in GitHub-hosted repos.
npm-pip-maven-audit
Configures and runs native package-manager audit commands across ecosystems - `npm audit --audit-level=high` (npm), `yarn npm audit` (Yarn 2+), `pnpm audit` (pnpm), `pip-audit` (Python via PyPA), `mvn dependency:check` (Maven via OWASP Dependency-Check plugin), `cargo audit` (Rust), `bundle audit` (Ruby Bundler); fastest no-install-required SCA option. Use when the team wants fast, no-extra-tooling SCA in CI as a first line of defense, or pairs with snyk/osv-scanner for layered coverage.
reachability-analyzer
Runs dead-dependency analysis across JS, Python, and Rust projects using ecosystem-native static tools (`depcheck`/`knip` for JS, `vulture` for Python, `cargo-machete` for Rust), then cross-references the unused-dependency list against SCA findings to downrank vulns in code that is never loaded. Use when SCA output (from `osv-scanner`, `snyk-test`, or `npm-pip-maven-audit`) is too noisy to triage and the team needs to separate unreachable CVEs from exploitable ones before sprint planning; sibling cve-exploitability-triage ranks by EPSS/KEV exploitation signal, not code reachability.
renovate-config
Reference for `renovate.json` - Mend Renovate dependency-update orchestrator (multi-platform: GitHub / GitLab / Bitbucket / Azure DevOps / Gitea); top-level keys (`extends` for preset references, `schedule`, `prConcurrentLimit`, `vulnerabilityAlerts`); `packageRules[]` array with `matchPackageNames` / `matchUpdateTypes` / `automerge` matching; `ignoreDeps`, `addLabels`, `automergeSchedule`. Use when authoring or reviewing Renovate configs in any repo platform Renovate supports.
snyk-test
Configures and runs Snyk, a commercial multi-mode scanner: snyk test for SCA (dependency scanning), snyk code test for SAST (code security scanning), snyk container test for container images, snyk iac test for IaC (infrastructure-as-code), snyk monitor for continuous new-vuln alerts; policy file .snyk for ignore + patch. Use when the team has a Snyk license and needs SCA (dependency scanning) or continuous vuln monitoring; for open-source scanning without a Snyk license, prefer osv-scanner.