Testland
Browse all skills & agents

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-scanner
View source

osv-scanner

When to use

  • Team prefers OSS tooling over commercial Snyk.
  • Layered SCA strategy - pair with snyk-test for cross-DB consensus signal.
  • Custom package manager produces SBOMs not natively supported; feed SBOM directly to OSV-Scanner.
  • Lightweight CI gate without commercial-license setup.

Step 1 - Install

Per osv-usage (opens in new window):

docker pull ghcr.io/google/osv-scanner:latest

Other 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/releases

Step 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.txt

Step 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:

FormatUse
--format jsonFor downstream aggregation
--format sarifGitHub Code Scanning upload
--format markdownPR comments
--format verticalDefault human-readable
--format htmlStandalone 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.json

This 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):

  • 0 - no vulnerabilities found
  • 1 - vulnerabilities found
  • 127 - config error

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

  • [[IgnoredVulns]] without ignoreUntil -> debt persists; always set ignoreUntil (Step 5).
  • Skipping --format=sarif upload -> findings invisible in the GitHub Security tab; always emit SARIF (Step 7).
  • Running only OSV-Scanner -> OSV.dev has its own coverage profile; layer with snyk-test.
  • Scanning without a committed lockfile -> manifest fallback resolves versions less accurately; commit the lockfile and scan via -L.
  • --config pointing outside the repo -> suppressions not auditable; commit osv-scanner.toml at the repo root.

Limitations

  • OSV.dev coverage varies by ecosystem (Python / npm / Go strong; less common ones thinner).
  • No reachability analysis: every CVE on a declared dep counts even if the vulnerable function isn't called.
  • Container image scanning is limited; prefer trivy-image or grype-scanning (qa-sbom plugin).
  • Some CLI surface evolves; verify against current osv-scanner help output.

References

  • osv-usage (opens in new window) - usage page (lockfile, SBOM, config)
  • Full osv-scanner.toml schema, triage template, and CI workflow: references/osv-scanner-config-and-ci.md
  • google.github.io/osv-scanner - full docs
  • github.com/google/osv-scanner - repository
  • osv.dev - OSV vulnerability database
  • ossf.github.io/osv-schema/ - OSV schema
  • snyk-test, dependabot-config, renovate-config, npm-pip-maven-audit - sister tools
  • syft-generation - cross-plugin SBOM source

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:

MechanismWhereUse
[[IgnoredVulns]] in osv-scanner.toml (with ignoreUntil)Repo rootPer-CVE; auditable in git
[[PackageOverrides]] in osv-scanner.tomlRepo rootPer-package version + ecosystem
--severity-threshold filter (when supported by version)CI flagScan-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.