The container image is the universal integration. Any platform that can run a container can run this, whether or not it has a dedicated page here.
The pattern
docker run --rm \
-v "$(pwd):/github/workspace" \
-w /github/workspace \
-e LOCK_FILE=requirements.txt \
-e OUTPUT_FILE=sbom.cdx.json \
-e ENRICH=true \
-e UPLOAD=false \
ghcr.io/sbomify/sbomify-actionThree things matter:
- Mount your repository.
/github/workspaceis the conventional path, but any path works as long as-wmatches. - Set the working directory with
-wso relative lockfile paths resolve. - Pass configuration as environment variables. The image entrypoint is
sbomify-action, so no command is needed.
Podman works identically - substitute podman run.
Uploading
docker run --rm \
-v "$(pwd):/github/workspace" \
-w /github/workspace \
-e TOKEN="$SBOMIFY_TOKEN" \
-e COMPONENT_ID=your-component-id \
-e LOCK_FILE=requirements.txt \
-e AUGMENT=true \
-e ENRICH=true \
ghcr.io/sbomify/sbomify-actionTake the token from your platform’s secret store rather than hardcoding it. Passing secrets with -e exposes them in the process list on the host; if that matters, use --env-file with a file mode of 0600, or your container runtime’s secret mechanism.
Caching
Use a named volume so the license database survives between runs:
docker volume create sbomify-cache
docker run --rm \
-v "$(pwd):/github/workspace" \
-v sbomify-cache:/cache \
-w /github/workspace \
-e SBOMIFY_CACHE_DIR=/cache/sbomify \
-e SYFT_CACHE_DIR=/cache/syft \
-e SBOMIFY_TOOL_CACHE=/cache/runtimes \
-e GITHUB_TOKEN="$GITHUB_TOKEN" \
-e LOCK_FILE=requirements.txt \
-e OUTPUT_FILE=sbom.cdx.json \
-e ENRICH=true \
-e UPLOAD=false \
ghcr.io/sbomify/sbomify-actionGITHUB_TOKEN matters on every platform. License databases are downloaded from GitHub Releases, and unauthenticated requests are capped at 60 per hour per IP. When that is exceeded, enrichment degrades silently. See license database rate limits.
Container images
Scanning an image needs access to a Docker daemon:
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$(pwd):/github/workspace" \
-w /github/workspace \
-e DOCKER_IMAGE=my-app:latest \
-e OUTPUT_FILE=container-sbom.cdx.json \
-e ENRICH=true \
-e UPLOAD=false \
ghcr.io/sbomify/sbomify-actionMounting the Docker socket gives the container control of the host daemon. Prefer a rootless or remote daemon where your platform supports it. Pulling from a registry rather than a local daemon avoids the socket entirely.
VCS information
Outside GitHub Actions, GitLab CI and Bitbucket, repository details are not auto-detected. Set them in sbomify.json:
{
"vcs_url": "https://git.example.com/my-org/my-repo",
"vcs_commit_sha": "abc123def456",
"vcs_ref": "main",
"supplier": {"name": "My Company"},
"lifecycle_phase": "build"
}Generate it from whatever variables your platform provides, then set AUGMENT=true. See augmentation.
Platform examples
The syntax differs; the substance does not.
Drone CI and Woodpecker
steps:
- name: generate-sbom
image: ghcr.io/sbomify/sbomify-action
commands:
- sbomify-action
environment:
LOCK_FILE: requirements.txt
OUTPUT_FILE: sbom.cdx.json
ENRICH: "true"
UPLOAD: "false"Buildkite
steps:
- label: "Generate SBOM"
plugins:
- docker#v5.11.0:
image: "ghcr.io/sbomify/sbomify-action"
workdir: /github/workspace
environment:
- LOCK_FILE=requirements.txt
- OUTPUT_FILE=sbom.cdx.json
- ENRICH=true
- UPLOAD=falseConcourse
jobs:
- name: generate-sbom
plan:
- get: repo
- task: sbom
config:
platform: linux
image_resource:
type: registry-image
source: { repository: ghcr.io/sbomify/sbomify-action }
inputs:
- name: repo
outputs:
- name: sbom
params:
LOCK_FILE: repo/requirements.txt
OUTPUT_FILE: sbom/sbom.cdx.json
ENRICH: "true"
UPLOAD: "false"
run:
path: sbomify-actionTeamCity has its own page.
A plain shell script - the docker run invocation at the top of this page works in cron, a Makefile, or a deployment script.
What is in the image
The image is deliberately small: Python, the sbomify CLI, conan for C and C++ metadata, and git.
Everything else - Syft, cdxgen, the JVM toolchain, Go, Rust, PHP, .NET, crane and cosign - is downloaded on first use, verified against a digest pinned at build time, and cached. You do not install anything; the tool fetches exactly the versions it was tested against.
Two practical consequences:
- Cache the runtimes or every run re-downloads them. Point
SBOMIFY_TOOL_CACHEat a volume, as in the caching example above. See tool runtimes. - Air-gapped runners need
SBOMIFY_FETCH_RUNTIMES=0, plus whatever generators you need preinstalled. Without them the run falls back to a lesser generator rather than failing, so check the output.
The container runs as root, because it needs to write to the mounted workspace. Files it creates will be root-owned on the host unless you pass --user.
Next steps
- Configuration reference - every option
- Augmentation - setting VCS details manually
- Advanced - caching, audit trail, troubleshooting