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:
| Command | Description |
|---|---|
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 k8s | Create SBOMs for the images running in a Kubernetes cluster. Experimental. |
Analysis, verification, and upload:
| Command | Description |
|---|---|
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:
| Variable | Default | Meaning |
|---|---|---|
OBSERVER_TOKEN | none | Access token. Required for upload. Without it, analyze uses a temporary namespace that is deleted after the request. |
OBSERVER_NAMESPACE | default | Namespace 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_ENDPOINT | https://cloud.sbom.observer | Set to your own URL for a self-hosted installation. |
export OBSERVER_TOKEN=your-api-tokenSee 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=falsewrites several SBOMs (default: stdout).-m, --merge: merge all components into one SBOM (trueby default);--merge=falsewrites one SBOM per component.--depth <n>: how many directory levels to read (default1).1reads only the directory you pass,2also 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
| Ecosystem | Package managers / targets |
|---|---|
| Go | modules, binaries |
| JavaScript | npm, yarn, pnpm |
| Python | pip, pyproject.toml, poetry, uv |
| Java | Maven, Gradle |
| .NET | NuGet |
| Ruby | Gem |
| PHP | Composer |
| Rust | Cargo |
| C/C++ | Conan |
| Elixir | mix, hex |
| Dart | pub |
| Swift | swift build |
| Crystal | shards |
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-binaryA 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 (trivydefault,syftalternative).
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:latestKubernetes 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 (trivydefault).
observer k8s --sbom --uploadSee 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 code1when a fail-build policy violation is present.
observer analyze my-app.cdx.jsonThe output has three sections: vulnerabilities, policy violations, and a summary.
./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 ./artifactsExits 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 isbasic. Without it, no retention runs.-n, --retention-keep <count>: versions to keep, counting this upload (default1).-d, --retention-keep-dependencies <true|false>: keep older versions whose component is a dependency of another component (defaulttrue).
See Retention policies for which versions count as the same SBOM.
export OBSERVER_TOKEN=your-api-token
observer upload my-app.cdx.jsonDiff
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
| Target | Scanner |
|---|---|
fs, Go, Python, and binaries | osv-scalibr, built in |
fs, npm and other ecosystems | Trivy if installed, otherwise osv-scalibr (the CLI logs a warning) |
fs, build observations | the build observations file from observer build |
image, k8s | Trivy (default) or Syft with --scanner syft; the binary must be installed |