Skip to main content

BOMpage

BOMpage

Software License semantic-release: angular Pipeline Status

Live demo BOMpage tracking its own dependencies

Track what your software is made of, across every project, over time.

Your CI already generates an SBOM — the list of every library your application depends on. But each one is a snapshot in a single pipeline: nobody can see them side by side, and nobody keeps yesterday's.

BOMpage collects those SBOMs into one Git repository and turns them into a dashboard you can publish on GitLab or GitHub Pages. It needs no server, no database and no account: the result is a folder of static files.

You can then answer, in a few clicks:

  • Which version of openssl does each of our services ship?
  • What changed in this application's dependencies since last month?
  • Are we still pulling a strong-copyleft licence anywhere?
  • Which project has stopped reporting? (its pipeline is probably broken)

How it fits together

Three pieces, set up in this order:

  your projects                central repo                  published site
 ┌──────────────┐        ┌───────────────────────┐        ┌─────────────────┐
 │ app-api   CI │──push─▶│ reports/app-api/      │        │                 │
 │ web-front CI │──push─▶│ reports/web-front/    │─build─▶│  a static page  │
 │ batch-etl CI │──push─▶│ reports/batch-etl/    │        │  (Pages)        │
 └──────────────┘        └───────────────────────┘        └─────────────────┘
   bompage push            one folder per project            bompage build
   (from each pipeline)    one file per day                  (from that repo's CI)
  1. Each project pushes its SBOM into the central repository at the end of its pipeline. A snapshot is only committed when the content actually changed, so the history stays readable.
  2. The central repository is just folders and JSON files. One directory per project, discovered automatically — nothing to declare, nothing to configure when a new project appears.
  3. Its own pipeline rebuilds the dashboard and publishes it.

Both SPDX and CycloneDX are accepted, so whatever your scanner emits (Trivy, Syft, the CycloneDX Maven plugin…) will work.

Install

Python 3.12 or later:

python3 -m pip install bompage
bompage --help

The published package already contains the dashboard, so you need nothing from the JavaScript world to use BOMpage.

Try it in two minutes

If you already have an SBOM file, put it in a folder named after your project and build:

mkdir -p reports/my-service
cp sbom.json reports/my-service/sbom-20260914.json   # sbom-YYYYMMDD.json

bompage build --reports reports --output public
python3 -m http.server -d public      # then open http://localhost:8000

A local file server is required: the page loads its data with fetch, which browsers refuse over file://.

The file name carries the date — sbom-YYYYMMDD.json, optionally sbom-YYYYMMDD-1.4.2.json to record a version. That is the whole convention; files that do not follow it are skipped with a warning rather than breaking the build.

The four commands

Every command accepts --help, and the full option reference is generated from the code, so it is always current.

bompage build — make the site

Runs in the central repository's pipeline. No network access needed.

bompage build --reports reports --output public \
  --stale-after 2 \
  --recent-days 30 \
  --metadata "team=platform"
  • --stale-after 2 — flag a project that has not reported for 2+ days.
  • --recent-days 30 — window covered by the "recent changes" panel.
  • --metadata "key=value" — free rows shown in the dashboard header; repeat it, or use --metadata-component "app-api:owner=backend" for one project.

Careful: --output is emptied on every build. BOMpage refuses to write into a folder it did not create itself; add --force only if you are sure.

bompage push — send one SBOM

Runs in each project's pipeline. Needs the git command and a write token.

export BOMPAGE_TOKEN=…

bompage push \
  --component app-api \
  --sbom build/sbom.cdx.json \
  --repo https://gitlab.com/acme/bompage.git
  • --component app-api — becomes reports/app-api/ in the central repo.
  • BOMPAGE_TOKEN — pass the token through the environment, not with --token: anything on a command line is readable by other processes on the same runner, and BOMpage warns you when you do.

Optionally, set BOMPAGE_SIGN_KEY to a private SSH key and push also writes a signed attestation sidecar (.att / .att.sig) beside the SBOM, which build then verifies (see bompage verify below). Leave it unset and nothing changes — signing is entirely opt-in.

On GitLab you usually do not call it by hand — include the ready-made component instead:

include:
  - component: gitlab.com/op_so/pages/bompage/push-report@v1
    inputs:
      component: app-api
      sbom_path: build/sbom.cdx.json
      bompage_repo: https://gitlab.com/acme/bompage.git
      bompage_version: "1.2.3"
      bompage_sign_key_var: BOMPAGE_SIGN_KEY # optional, see deploy/README.md

bompage prune — keep the repository small

Deletes snapshots older than --keep-days in a single ordinary commit — no history rewriting. The most recent snapshot of each project is always kept, so a project that went quiet stays visible on the dashboard.

export BOMPAGE_TOKEN=…

bompage prune \
  --repo https://gitlab.com/acme/bompage.git \
  --keep-days 90 \
  --dry-run

--dry-run lists what would go without changing anything; drop it to actually commit. Best run as a scheduled job in the central repository.

bompage verify — check a download

Run by anyone who downloaded an SBOM, not by a pipeline. Needs no repository access, only the file, its .att / .att.sig sidecars, and the trust root. Today those sidecars live only in the central repo's reports/<component>/ tree — the published site does not yet serve them (a planned dashboard change, see the spec):

bompage verify reports/app-api/sbom-20260914.json --allowed-signers ./allowed_signers

It is a convenience only: the same check can always be done with stock ssh-keygen, jq and sha256sum alone, which is documented in docs/verify.md for anyone who does not want to trust bompage itself for that. This only matters for a deployment that signs its pushes (see BOMPAGE_SIGN_KEY above) — an unsigned one has nothing here to verify.

Set up a central repository

The deploy/ folder is a ready-to-copy skeleton: the layout, the Pages job and the scheduled prune job. See deploy/README.md for the steps.

What the dashboard shows

A live one is published at op_so.gitlab.io/pages/sbom-bompage: BOMpage runs the whole flow on itself, so that page is built by the released version from an SBOM its own pipeline pushed.

Per project: the current inventory (name, version, ecosystem, licence), with strong-copyleft dependencies flagged; the version history of any package; what was added and removed recently; a comparison between any two snapshots; and a warning when a project has stopped reporting.

Across projects: a search for any package name, and the list of dependencies sitting at diverging versions in several projects of the same ecosystem.

Not built yet: the versioned api/v1/ REST surface, for tools that would read this data rather than look at it.

Contributing

Bug reports and merge requests are welcome. The development setup, the test suite and the quality gates are documented in CONTRIBUTING.md.

Authors

License

This program is free software: you can redistribute it and/or modify it under the terms of the MIT License (MIT). See the LICENSE for details.

Release files for bompage 1.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bompage 1.2.2
File Size Uploaded
bompage-1.2.2.tar.gz 1.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for bompage 1.2.2
File Interpreter ABI Platform
bompage-1.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / bompage-1.2.2.tar.gz

Download URL bompage-1.2.2.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
60403f0d528440a9a0dc294dbbb40da490d653fc6213514cb3291473a7b8686b
BLAKE2b-256 checksum
How to use checksums
52eefd9a74a61943df49e60960a87396bc2a3ab50d6e8609f07453792c204d78
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / bompage-1.2.2-py3-none-any.whl

Download URL bompage-1.2.2-py3-none-any.whl
Size 606.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e767c2fe1accbb7921a10c75da17883b0bd8f602e302b1a7b61c526eea7bf3f
BLAKE2b-256 checksum
How to use checksums
d5255e5863179b42554b7d2d3b1a0bcb07c9f586cf58a04b2ec653f984920f8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

1.3.1

2 release files

1.3.0

2 release files

This release

1.2.2 This release

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page