CLI

Observer CLI commands, flags, and environment variables.

Observer CLI generates CycloneDX SBOMs from source code, container images, Kubernetes clusters, and builds. It also analyzes SBOMs against SBOM Observer and uploads them. It is open source under the Apache 2.0 license: github.com/sbom-observer/observer-cli.

Installation

Download the archive for Linux, macOS, or Windows from the releases page, unpack it, and put the observer binary on your PATH.

Command overview

SBOM generation and capture:

CommandDescription
observer fs [path]Scan filesystem directories (source code, binaries, monorepos).
observer image [image]Scan container images (Docker, OCI).
observer build [-- command]Observe a build process and capture dependencies (C/C++, mixed-language).
observer k8sCreate SBOMs for the images running in a Kubernetes cluster. Experimental.

Analysis, verification, and upload:

CommandDescription
observer analyze [sbom]Analyze an SBOM for vulnerabilities and policy violations.
observer upload [sbom...]Upload SBOMs to SBOM Observer, with optional retention policies.
observer verify <sbom>Validate CycloneDX structure and optionally compare artifacts.
observer diff <sbom> <sbom>Compare two CycloneDX JSON SBOMs and show the differences.

Global flags: --debug (debug logging, implies silent mode), --silent (no progress bars), -h, --help. Command-specific flags are listed in each section below; run observer [command] --help for the full set.

Authentication

Commands that talk to SBOM Observer read these environment variables:

VariableDefaultMeaning
OBSERVER_TOKENnoneAccess token. Required for upload. Without it, analyze uses a temporary namespace that is deleted after the request.
OBSERVER_NAMESPACEdefaultNamespace to upload to and analyze against: the part of the app URL after /workspace/. Must be the namespace the token was created in, or the request is rejected.
OBSERVER_ENDPOINThttps://cloud.sbom.observerSet to your own URL for a self-hosted installation.
export OBSERVER_TOKEN=your-api-token

See Access tokens for generating and managing tokens.

Metadata configuration

An observer.yaml file in the repository root configures SBOM metadata:

component:
  type: application
  name: my-application
  group: my-group
  version: 1.0.0
  description: Description of component
  license: MIT
supplier:
  name: Supplier Name
  url: https://example.com
  contacts:
    - name: John Doe
      email: john.doe@example.com
      phone: "123"

These values fill the SBOM's top-level component and supplier, fields that scanners can't detect on their own and that policies such as NTIA minimum elements check for.

For a monorepo, place observer.yaml in the root of each component subdirectory. For the layout below, scan with --depth 3, since each manifest sits two directories below the root:

my-monorepo/
├─ apps/
│  ├─ web/
│  │  ├─ observer.yaml   # metadata for the web app
│  │  ├─ package.json
│  │  └─ src/
│  └─ api/
│     ├─ observer.yaml   # metadata for the API
│     ├─ go.mod
│     └─ cmd/
└─ libs/
   ├─ shared-ui/
   │  ├─ observer.yaml   # metadata for shared UI library
   │  ├─ package.json
   │  └─ src/
   └─ core/
      ├─ observer.yaml   # metadata for core library
      ├─ pyproject.toml
      └─ src/

Filesystem scanning

Command: observer fs [path]

Scans a source directory and writes a CycloneDX JSON SBOM. It detects the ecosystems in use and, in a monorepo, each component's subdirectory.

Key flags:

  • -o, --output <path>: output file, or a directory when --merge=false writes several SBOMs (default: stdout).
  • -m, --merge: merge all components into one SBOM (true by default); --merge=false writes one SBOM per component.
  • --depth <n>: how many directory levels to read (default 1). 1 reads only the directory you pass, 2 also its direct subdirectories, and so on.
  • -v, --vendor <path>: include vendor directories (repeatable).
  • -a, --artifacts <path>: add build artifacts that make up the scanned software to the merged SBOM.

fs detects packages with Trivy when it is installed, or with the built-in osv-scalibr. See Scanners. To upload the result, run observer upload.

Supported ecosystems

EcosystemPackage managers / targets
Gomodules, binaries
JavaScriptnpm, yarn, pnpm
Pythonpip, pyproject.toml, poetry, uv
JavaMaven, Gradle
.NETNuGet
RubyGem
PHPComposer
RustCargo
C/C++Conan
Elixirmix, hex
Dartpub
Swiftswift build
Crystalshards

These are the ecosystems observer fs reads. SBOM Observer analyzes more than these, including OS packages; see Ecosystems.

# Scan an npm project
cd ~/src/webapp
observer fs -o my-app.cdx.json .

# Scan a compiled Go binary
cd ~/src/my-go-app
observer fs -o my-app.cdx.json ./dist/my-app-binary

A Go binary records the modules compiled into it and the Go version that built it, so scanning the binary lists what ships. Scanning the source reads go.mod instead, which can also name modules the binary doesn't contain.

In a monorepo, fs finds each component directory within --depth. Ecosystems in the same directory, for example go.mod and package-lock.json, become one SBOM for that component. By default, all components are then merged into one SBOM; with --merge=false and -o <directory>, each component gets its own file.

Container image scanning

Command: observer image [image]

Generates an SBOM from a container image, analyzing OS packages and application dependencies.

Key flags:

  • -o, --output <file>: write the SBOM to a file (default: stdout).
  • -u, --upload: upload the generated SBOM to SBOM Observer.
  • --scanner trivy|syft: choose the backend (trivy default, syft alternative).

The scanner must be installed. See Scanners.

observer image -o my-app.cdx.json hello-world:latest
observer image --scanner syft -o app.cdx.json docker.io/library/nginx:latest

Kubernetes cluster scanning

Command: observer k8s

Finds the images running in a cluster, using the current kubectl context, and can create an SBOM for each one. Experimental: the command may change or be removed.

Key flags:

  • -s, --sbom: create an SBOM for every image in the cluster.
  • -u, --upload: upload the image SBOMs to SBOM Observer. A snapshot of the cluster's resources is uploaded too, but SBOM Observer doesn't import it.
  • -n, --namespace <name>: limit the snapshot to these Kubernetes namespaces (default: all).
  • --kubeconfig <path>: kubeconfig file to use.
  • -o, --output <dir>: output directory (default: stdout).
  • --scanner trivy|syft: scanner for the image SBOMs (trivy default).
observer k8s --sbom --upload

See Generate SBOMs for containers and Kubernetes.

Analyze, verify, and upload

Analyze

Command: observer analyze [sbom]

Sends an SBOM to SBOM Observer and prints the vulnerabilities and policy violations found. The command exits non-zero only if the request fails, or when --fail is set and at least one violation configured with action: fail-build is present. See Enforce policies in CI/CD for setting this up.

Key flags:

  • --summary, -s: show only the summary table.
  • --fail: exit with code 1 when a fail-build policy violation is present.
observer analyze my-app.cdx.json

The output has three sections: vulnerabilities, policy violations, and a summary.

Terminal output
./observer analyze example-nextjs.cdx.json
Analyzed example-nextjs.cdx.json

 -- Vulnerabilities --
┌─────────────────┬─────────┬─────────────────────┬──────────┬────────┬──────────────────┬─────────────────────────────────────────────────────────────────┐
│      Name       │ Version │     Identifier      │ Severity │  EPSS  │ Patched Versions │                              Title                              │
├─────────────────┼─────────┼─────────────────────┼──────────┼────────┼──────────────────┼─────────────────────────────────────────────────────────────────┤
│ next            │ 13.5.3  │ CVE-2025-29927      │ CRITICAL │ 92.08% │ >=13.5.7         │ nextjs: Authorization Bypass in Next.js Middleware               │
├─────────────────┼─────────┼─────────────────────┼──────────┼────────┼──────────────────┼─────────────────────────────────────────────────────────────────┤
│ zod             │ 3.21.4  │ CVE-2023-4316       │ HIGH     │ 0.14%  │                  │ Zod denial of service vulnerability                              │
└─────────────────┴─────────┴─────────────────────┴──────────┴────────┴──────────────────┴─────────────────────────────────────────────────────────────────┘

 -- Policy Violations --
┌──────────┬──────────────────┬────────────────────────────────┬────────────────────────────────────────┬──────────┐
│   Name   │     Version      │             Policy             │                Message                 │ Severity │
├──────────┼──────────────────┼────────────────────────────────┼────────────────────────────────────────┼──────────┤
│ frontend │ 85448d7aa1f38ad3 │ NTIA Minimum Elements for SBOM │ metadata.supplier is missing            │ MEDIUM   │
└──────────┴──────────────────┴────────────────────────────────┴────────────────────────────────────────┴──────────┘

 -- Summary --
┌───────────────────┬──────────┬──────┬────────┬─────┬───────┐
│                   │ CRITICAL │ HIGH │ MEDIUM │ LOW │ Total │
├───────────────────┼──────────┼──────┼────────┼─────┼───────┤
│ Vulnerabilities   │ 1        │ 1    │ 0      │ 0   │ 2     │
├───────────────────┼──────────┼──────┼────────┼─────┼───────┤
│ Policy Violations │ 0        │ 0    │ 1      │ 0   │ 1     │
└───────────────────┴──────────┴──────┴────────┴─────┴───────┘

Verify

Command: observer verify <sbom>

Validates that a CycloneDX SBOM is well-formed and, optionally, that generated artifacts match the hashes recorded in it.

Key flag: --artifacts <dir>, a directory of build artifacts to hash and compare against the SBOM's entries.

# Validate structure only
observer verify sbom.cdx.json

# Validate against produced artifacts
observer verify sbom.cdx.json --artifacts ./artifacts

Exits non-zero when the SBOM fails validation, an artifact is missing, or a hash mismatch is found.

Upload

Command: observer upload [sbom...]

Uploads one or more SBOMs or other attestations to the namespace in OBSERVER_NAMESPACE.

Key flags:

  • -p, --retention-policy <name>: retention policy to apply; the only one is basic. Without it, no retention runs.
  • -n, --retention-keep <count>: versions to keep, counting this upload (default 1).
  • -d, --retention-keep-dependencies <true|false>: keep older versions whose component is a dependency of another component (default true).

See Retention policies for which versions count as the same SBOM.

export OBSERVER_TOKEN=your-api-token
observer upload my-app.cdx.json

Diff

Command: observer diff <sbom> <sbom>

Compares two CycloneDX JSON SBOMs and prints the components that differ.

Key flags:

  • -a, --all: list all components, not only the differences.
  • -p, --include-purl: include package URLs in the output.
  • -m, --markdown: write the result as Markdown.
  • -o, --output <file>: write to a file (default: stdout).

CI/CD integration

analyze --fail fails a pipeline step when a violation has the fail-build action. See Enforce policies in CI/CD for the policy side and CI/CD integration for a complete GitHub Actions workflow.

SBOM formats and tool integration

Observer CLI writes CycloneDX JSON. analyze and upload also take CycloneDX and SPDX SBOMs from other tools. See Formats and standards for versions, and Generate SBOMs at build time for C/C++ and mixed-language builds.

SBOMs from other tools, such as Trivy, Syft, or cdxgen, can be uploaded and analyzed as long as they are CycloneDX or SPDX. diff only reads CycloneDX JSON.

Scanners

TargetScanner
fs, Go, Python, and binariesosv-scalibr, built in
fs, npm and other ecosystemsTrivy if installed, otherwise osv-scalibr (the CLI logs a warning)
fs, build observationsthe build observations file from observer build
image, k8sTrivy (default) or Syft with --scanner syft; the binary must be installed