Skip to main content

BOMpage

BOMpage

Software License semantic-release: angular Pipeline Status

Built with Material for MkDocs Source code documentation

A generic, server-less system to centralise the SBOM history of N components in a dedicated Git repository and publish a static dashboard (GitLab / GitHub Pages) plus an optional static REST API.

Status: SPDX and CycloneDX. Covered: last known state (§7.1), per-package timeline & recent changes (§7.2), data freshness (§7.5), transverse search (§7.3) and cross-component version drift (§7.4), snapshot retention (§5.4), plus the reusable CI push component (§9). Not yet: the arbitrary two-date diff (§7.6) and the versioned api/v1/ surface (§8).

What it does

From a central bompage repository laid out as reports/<component>/sbom-YYYYMMDD[-version].json, the bompage CLI:

  • discovers components dynamically (one directory = one component);
  • parses every dated snapshot of each component (SPDX and CycloneDX, including CycloneDX nested sub-components) into a common inventory model;
  • derives, per component: current inventory (name, version, ecosystem from the purl, licence, strong-copyleft flag), the per-package version timeline, the added/removed deltas, a recent-changes feed and a freshness verdict;
  • builds a cross-component inverted index (package → components) and the list of active version drifts;
  • writes a JSON data tree under public/data/ (index.json, sbom-data.json, components/<name>.json, packages-index.json, drifts.json) plus a copy of each raw manifest;
  • ships a constant dashboard page (no project data baked in) that fetches that tree at runtime: per-component tabs with a stale badge, ecosystem filter, client-side search, a recent-changes panel, a click-through version timeline, a global transverse search and an "active drifts" view.

Ingestion is the push-report reusable GitLab CI/CD component (spec §9): it pip installs a pinned bompage release and runs bompage push, which clones the central repo with a scoped token, drops the SBOM under reports/<component>/ and commits only if the content changed (anti-noise filter, §10). The logic lives in src/bompage/push.py (it shells out to git; no VCS library).

Retention is bompage prune (spec §5.4, src/bompage/prune.py): it removes snapshots older than --keep-days (default 90) from reports/ in one ordinary commit — no history rewrite — always keeping each component's most recent snapshot, and runs as a scheduled job in the central repo's own pipeline. Shared git plumbing sits in src/bompage/_git.py.

The page is built with Material Web (Material Design 3) + lit, bundled by Vite, with Roboto and a subset of Material Symbols self-hosted (no CDN, no runtime network call).

Usage

Usage: bompage [OPTIONS] COMMAND [ARGS]...

  Track SBOM history of N components and build a static dashboard.

Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

Commands:
  build  Build the static dashboard and its data/ tree from a reports/ tree.
  push   Publish one SBOM into the central repository (clone, commit iff changed, push).
  prune  Remove SBOM snapshots older than --keep-days from the central repository.

Every command also accepts --help. Full generated reference: CLI documentation.

bompage build

Build the static dashboard and its data/ tree from a reports/ tree. Runs locally or in the central repo's Pages job; needs no network access.

Option Default Description
--reports PATH reports Directory holding one sub-directory per component (must exist).
--output PATH public Directory the static site is written to.
--web-dir PATH (packaged assets) Pre-built dashboard (index.html + assets/) to use instead of the one bundled in the wheel.
--stale-after N 2 A component with no new report for more than N days is flagged stale (min 0).
--recent-days N 30 Sliding window, in days, for the dashboard's recent-changes feed (min 1).
--metadata "key=value" Global metadata row shown in the dashboard header. Repeatable.
--metadata-component "component:key=value" Per-component metadata row. Repeatable.
bompage build --reports reports --output public \
  --stale-after 2 --recent-days 30 \
  --metadata "team=platform" --metadata-component "app-api:owner=backend"

bompage push

Publish one SBOM into the central repository: clone with a scoped token, drop the file under reports/<component>/, and commit only if the content changed (anti-noise filter, spec §10), then push. Requires the git binary on PATH.

Option Default Description
--component TEXT required Logical component name (one directory under reports/).
--sbom PATH required Path to the SBOM file produced by the calling job (must exist).
--repo TEXT required HTTPS clone URL of the central bompage repository.
--token TEXT required — env BOMPAGE_TOKEN Scoped write token for the central repository.
--branch TEXT main Target branch in the central repository.
--sbom-version TEXT Version suffix appended to the SBOM file name.
--sbom-format TEXT Informative (spdx | cyclonedx); recorded in the commit message.
--git-user TEXT bompage-ci Commit author name.
--git-email TEXT bompage-ci@localhost Commit author email.
export BOMPAGE_TOKEN=            # scoped write token
bompage push \
  --component app-api \
  --sbom build/sbom.cdx.json \
  --sbom-format cyclonedx \
  --repo https://gitlab.com/acme/bompage.git

bompage prune

Remove SBOM snapshots older than --keep-days from reports/ in a single ordinary commit — no history rewrite — always keeping each component's most recent snapshot (spec §5.4). Same git-on-PATH and token requirements as push; runs as a scheduled job in the central repo's own pipeline.

Option Default Description
--repo TEXT required HTTPS clone URL of the central bompage repository.
--token TEXT required — env BOMPAGE_TOKEN Scoped write token for the central repository.
--branch TEXT main Target branch in the central repository.
--keep-days N 90 Snapshots older than N days are removed; the most recent snapshot of each component is always kept (min 1).
--dry-run (off) List what would be removed without committing or pushing.
--git-user TEXT bompage-ci Commit author name.
--git-email TEXT bompage-ci@localhost Commit author email.
export BOMPAGE_TOKEN=…
bompage prune --repo https://gitlab.com/acme/bompage.git --keep-days 90 --dry-run

Preview locally

Preview with any static file server (the page uses fetch, so it will not run from file://):

bompage build --reports reports --output public
python3 -m http.server -d public

Installation

With Python environment

  • Minimal Python version: 3.14
python3 -m pip install bompage
bompage --help

The published wheel ships the pre-built dashboard, so no JS toolchain is needed to use bompage.

From source

The dashboard assets (src/bompage/web/) are a Vite build output and are not committed. JS dependencies are managed with pnpm. Build them once before running the tests or bompage build:

brew install pnpm  # or: corepack enable && corepack prepare pnpm@11 --activate
fnm use            # Node 24, per .node-version
pnpm install --frozen-lockfile
pnpm run build:web # -> src/bompage/web/  (or: task 00:010-build-web)

The dashboard sources are checked with Biome + tsc (pnpm run lint:web, pnpm run typecheck:web, pnpm run format:web; task 00:015-check-web). task 00:190-check runs the whole static battery, task 00:290-check-all adds the tests. Tests that need the built page skip cleanly until it is built; the browser smoke test is uv run pytest -m e2e (needs uv run playwright install chromium).

Tests

task 00:010-build-web
uv run python scripts/gen-demo-data.py
uv run python -m http.server -d public 8000

Deployment

The deploy/ directory is a scaffold for bootstrapping a central bompage repository — the pages job plus a scheduled bompage prune job (see deploy/README.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.0.0

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.0.0
File Size Uploaded
bompage-1.0.0.tar.gz 382.4 kB Details

Built distribution (wheel)

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

Total release size: 417.5 kB

Release files / bompage-1.0.0.tar.gz

Download URL bompage-1.0.0.tar.gz
Size 382.4 kB
Tags Source
SHA-256 checksum
How to use checksums
6445da001660517b41eac2a20536e9fa8e814f655d7a1850a0120893ea40553c
BLAKE2b-256 checksum
How to use checksums
96a5d966edec4e8ee25e1d944e9f4de4cdc73a0e9b372607f7e89a9483fed420
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","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.0.0-py3-none-any.whl

Download URL bompage-1.0.0-py3-none-any.whl
Size 35.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f4382250c5e8a9051cebaffbd602c44bba2bf0b73c8d1f1a804ca84dd703d25c
BLAKE2b-256 checksum
How to use checksums
ffb1f14157215e5eec7702066ea7678e829bcd6b25c5551c059b0c2379527cb8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","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

1.2.2

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

This release

1.0.0 This release

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