CLI tool
google/osv-scalibr avatar
google/osv-scalibr

OSV-SCALIBR extracts software inventory, finds known flaws and writes SBOMs

OSV-SCALIBR: A library for Software Composition Analysis

648 stars209 forksGoApache-2.0

At a glance

What is it?
OSV-SCALIBR is an extensible Go library for software composition analysis that scans filesystems and container images to build a package inventory, detect known vulnerabilities and emit SPDX or CycloneDX documents, with plugins for extraction, detection, annotation and enrichment. It suits a security team that wants the inventory step under its own control, and the plugin model is the whole design.
Who is it for?
Adopt OSV-SCALIBR when you need to own the inventory step in your scanning pipeline, when you want to write your own extraction or detection plugins, or when you need SPDX output from the same scan that finds vulnerabilities. Do not adopt it if you just want a scanner, since the README says not all of its functionality is available through the OSV-Scanner CLI yet and points to a migration guide.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Inventory first, vulnerabilities as a consequence

OSV-SCALIBR, the Software Composition Analysis Library, is described as an extensible library for a specific pipeline. The first capability is a file system scanner used to extract software inventory data, such as installed language packages, and then to detect known vulnerabilities or generate SBOMs, with a linked list of currently supported software inventory types. Container analysis functionality comes next, including layer-based extraction. Guided Remediation, generating upgrade patches for transitive vulnerabilities, is the third. The ordering is the important part. Most scanners start from a vulnerability database and look for package names in a lockfile, which means they only see what a lockfile declares. SCALIBR starts from the filesystem, so it sees what was actually installed, including packages that arrived as transitive dependencies and were never written into a manifest. That inventory is then reused for three different jobs, vulnerability matching, SBOM generation and remediation, rather than being rebuilt for each one.

Three ways in, and the CLI covers less than the library

There are three entry points, and the README is careful about the difference between them. The OSV-Scanner CLI is the route for known vulnerability scanning and extraction in a CLI context, with a note that not all OSV-SCALIBR functionality is available via OSV-Scanner yet and a migration guide for what moved where. The wrapper binary is the quickest way to try the library itself, installed with go install github.com/google/osv-scalibr/binary/scalibr@latest and then run with scalibr --result=result.textproto, where the result proto definition in binary/proto/scan_result.proto describes the output format and scalibr --help lists the remaining arguments. As a library, the sequence is to import github.com/google/osv-scalibr into a Go project, create a scalibr.ScanConfig struct and configure the extraction and detection plugins, then call scalibr.New().Scan() with the config and parse the returned scalibr.ScanResults. The scan result is a proto rather than JSON by default, which is worth knowing because it means you either parse a proto or ask for a textproto file.

Container images scan by remote reference or from a tarball

Scanning a container image does not require pulling and unpacking it yourself. The --remote-image flag scans a remote container image, and the --image-tarball flag scans a locally saved tarball such as one produced with docker save. Both are one-line invocations against the same binary:

bash
scalibr --result=result.textproto --remote-image=alpine@sha256:0a4eaa0eecf5f8c050e5bba433f58c052be7587ee8af3e8b3910ef9ab5fbe9f5
bash
scalibr --result=result.textproto --image-tarball=my-image.tar

Two things are worth reading closely in those examples. The remote image is pinned by digest rather than by tag, which is the right way to scan an image you can actually identify, and it also means the scan is reproducible. And the platform limit is explicit: only linux-based container images are supported currently, with issue 953 tracking Windows image container scanning support. The layer-based extraction mentioned in the feature list is what makes a container scan different from a filesystem scan, since the inventory has to be attributed to the layer that introduced each package rather than merged into one flat view. The repository carries run_scalibr_on_image.sh at the top level and an artifact/ directory, which suggests the image handling is a first class part of the codebase rather than an afterthought.

SPDX output, with the document fields you can override

Generating an SBOM is a flag rather than a separate tool. OSV-SCALIBR supports generating the result of inventory extraction as an SPDX v2.3 file in json, yaml or tag-value format, so scalibr -o spdx23-json=result.spdx.json produces one directly from the same scan that found the vulnerabilities. The document fields are not entirely fixed, and the README shows how to overwrite some of them. The spdx-document-name, spdx-document-namespace and spdx-creators flags set those three, with the creators value given as Organization:Google in the example:

bash
scalibr -spdx-document-name="Custom name" --spdx-document-namespace="Custom-namespace" --spdx-creators=Organization:Google -o spdx23-json=result.spdx.json

The namespace override is the field that matters most in practice, because a namespace is what makes an SPDX document identifier unique, and a document that shares a namespace with another cannot be distinguished by a consumer. The dependency list also carries github.com/CycloneDX/cyclonedx-go at 0.11.0 alongside the SPDX support, so the CycloneDX format is in the dependency set even though the README's examples only show SPDX output.

Plugins are the unit of extension, and there are five kinds

The plugin model is the substance of the project, and the README names five categories with the definition files that list them all: extractors for the filesystem and for the standalone case, detectors, annotators and enrichers. The binary runs the recommended internal plugins by default and you enable more with the --plugins= flags, while as a library you import plugin/list and add plugin names to the scan config. The example shows the shape, with plugins resolved by name and handed to the config:

go
import (
  "context"
  scalibr "github.com/google/osv-scalibr"
  pl "github.com/google/osv-scalibr/plugin/list"
  scalibrfs "github.com/google/osv-scalibr/fs"
)
plugins, _ := pl.FromNames([]string{"os", "cis", "vex"})
cfg := &scalibr.ScanConfig{
  ScanRoots: scalibrfs.RealFSScanRoots("/"),
  Plugins:   plugins,
}
results := scalibr.New().Scan(context.Background(), cfg)

The three names in the example give a taste of what is built in. An os extractor reads package manifests from the operating system, cis is the CIS benchmark check content, and vex is the VEX format for vulnerability exploitability, which is how a scan can record that a finding is not exploitable in your context rather than only that a package version matches a known bad release. The vocabulary of the five categories is worth learning because it tells you where your own code should live: an extractor pulls something out of the filesystem, a detector looks at the inventory and reports a finding, an annotator adds information to an existing result, and an enricher adds external context.

Capabilities let a plugin set adapt to the host

Not every plugin can run everywhere, and the library gives you a way to say what the scanning host can do rather than discovering it through failures. You specify the host's capabilities to enable only plugins whose requirements are satisfied, with examples such as network access and OS-specific plugins:

go
import (
  ...
  "github.com/google/osv-scalibr/plugin"
)
capab := &plugin.Capabilities{
  OS:            plugin.OSLinux,
  Network:       plugin.NetworkOnline,
  DirectFS:      true,
  RunningSystem: true,
}
...
cfg := &scalibr.ScanConfig{
  ScanRoots: scalibrfs.RealFSScanRoots("/"),
  Plugins:   plugin.FilterByCapabilities(plugins, capab),
}
...

The DirectFS and RunningSystem flags are the ones that catch people out. DirectFS asks whether the scanner can read the filesystem directly rather than through a mounted image, and RunningSystem asks whether the scanner is on the system being scanned, which matters for plugins that read live process or package manager state rather than files on disk. Getting these wrong produces a scan that silently under-reports, which is the worst failure mode for an inventory tool. Filtering by capabilities rather than by hand-picking plugin names also means a plugin set can be shared between a container scan and a host scan without editing the configuration for each, which is what makes the same pipeline usable in CI and on a fleet machine.

Custom plugins are library only, and cross-platform work has rules

Custom plugins can only be run when using OSV-SCALIBR as a library, so the standalone binary is not a path for extending it. The two interfaces to implement are the Extractor and the Detector, and once you have written one you add the struct to the scan config and run the scan. The cross-platform guidance is the part that separates a plugin that works from one that breaks someone else's build. OSV-SCALIBR is compatible with Linux and has experimental support for Windows and Mac, and when a new plugin is implemented the project needs to ensure it does not break other platforms. The runners will generally catch compatibility issues, but the recommendations are given anyway. Work with file paths using the filepath library, preferring filepath.Join('my', 'path') over '/my/path'. If a plugin can only support one system, the layout is generally two versions of the file, a file_system.go where system is the targeted system, such as file_windows.go, containing the code specific to the target system with the appropriate go build constraint, and a file_dummy.go that contains the code for every other system, generally doing nothing beyond ensuring the code compiles there. Because of the way the internal automation works, unit tests are generally required for every platform and filtered out dynamically if not compatible.

Editorial conclusion

Adopt OSV-SCALIBR when you need to own the inventory step in your scanning pipeline, when you want to write your own extraction or detection plugins, or when you need SPDX output from the same scan that finds vulnerabilities. Do not adopt it if you just want a scanner, since the README says not all of its functionality is available through the OSV-Scanner CLI yet and points to a migration guide. Verify first that the inventory types you care about are in the supported list, that your container images are Linux based since Windows image support is tracked in issue 953, and that the plugins you enable match the capabilities of the host you scan, since network access and OS-specific plugins are filtered by that declaration.

Frequently asked questions

How do I install and run OSV-SCALIBR?

Install the wrapper binary with go install github.com/google/osv-scalibr/binary/scalibr@latest and run scalibr --result=result.textproto, or build it from source with make scalibr, which sets CGO_ENABLED=1 because the RPM extractor depends on go-sqlite3. Run scalibr --help for the remaining arguments.

What output formats does OSV-SCALIBR produce?

Inventory extraction results can be written as SPDX v2.3 in json, yaml or tag-value format, for example scalibr -o spdx23-json=result.spdx.json, with flags to override the spdx-document-name, spdx-document-namespace and spdx-creators fields. The default result output is a proto, described in binary/proto/scan_result.proto.

Can OSV-SCALIBR scan Windows container images?

Not yet. The README states that only linux-based container images are supported currently, and points to issue 953 for tracking Windows image container scanning support. The library itself is compatible with Linux and has experimental support for Windows and Mac.

How do I write my own plugin for OSV-SCALIBR?

Custom plugins can only be run when using OSV-SCALIBR as a library. You create an implementation of the Extractor or Detector interface, add the new struct to the scan config and run the scan. For OS-specific plugins the project asks for a file_system.go with the build constraint and a file_dummy.go that compiles on every other system, plus unit tests for every platform.

Official sources

  1. google/osv-scalibr on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-osv-scalibr.svg)](https://hysenlabs.com/projects/google-osv-scalibr)

Was this useful?