Release SBOMs
Each Eneo release includes Software Bill of Materials (SBOM) files for the published backend and frontend container images. The files are attached to the GitHub Release so you can download the dependency inventory for the exact version you run.
The release workflow covers:
ghcr.io/eneo-ai/eneo-backend:<version>ghcr.io/eneo-ai/eneo-frontend:<version>
For a release tag such as v2.0.0, the image tag is 2.0.0.
The SBOM filenames use the release tag, including the v prefix. Prereleases
use the same process, so a tag such as v2.0.0-rc.2 gets SBOM files for that
prerelease.
How the release flow works
When maintainers publish a GitHub Release, the release SBOM workflow runs automatically:
- The workflow reads the release tag and derives the container image tag.
- It checks out the release tag for source-based dependency inventory.
- It waits for the matching backend and frontend images in GitHub Container Registry.
- It resolves the immutable
linux/amd64image digest for each image. - It scans those digest references, not only the mutable image tags.
- It installs frontend dependencies with Bun’s frozen lockfile and generates a frontend source dependency SBOM.
- It uploads the generated files to the same GitHub Release page.
- It attests the release SBOM assets with GitHub artifact attestations.
Each release keeps its own SBOM files. Older release pages keep their original assets, so you can compare one version with the next. The backend and frontend container images also get provenance attestations when they are built and pushed to GitHub Container Registry.
The same workflow can also run manually as a dry run. In dry-run mode it creates the files as a temporary workflow artifact and does not attach them to the GitHub Release.
The diagram follows the same path as the release workflow:
Why Eneo uses more than one SBOM file
Eneo publishes a small set of files because each file answers a different question.
The backend and frontend image SBOMs are the main release inventory. They are generated with Syft , which scans container images and filesystems and can export several SBOM formats. For Eneo, Syft scans the released backend and frontend image digests and creates:
- CycloneDX JSON for tools that consume the CycloneDX SBOM standard.
- SPDX JSON for tools and processes that use SPDX.
- A readable package table for quick human review.
The backend also has a narrower Python runtime SBOM. It is generated with the
CycloneDX Python tool from the
Python environment installed at /app/.venv inside the released backend image.
This file is useful when you specifically want the backend Python dependency
inventory. It does not replace the full backend image SBOM because it does not
describe the whole container image.
Eneo scans the released image digests instead of source lockfiles because the image digest is the shipped artifact. Lockfiles describe build input; the image describes what users receive.
There is one deliberate exception: the frontend source dependency SBOM. The frontend runtime image contains the bundled build output, not the full Bun workspace dependency tree. The source dependency SBOM keeps the JavaScript dependency inventory visible for scanners and reviewers. Treat it as build-input dependency inventory, not as a byte-for-byte inventory of the runtime image.
Files on the release page
Each release publishes these files:
| File | Purpose |
|---|---|
eneo-backend-<release-tag>-linux-amd64.cyclonedx.json | Backend image SBOM in CycloneDX JSON |
eneo-backend-<release-tag>-linux-amd64.spdx.json | Backend image SBOM in SPDX JSON |
eneo-backend-<release-tag>-linux-amd64.table.txt | Backend image package list for human review |
eneo-backend-python-runtime-<release-tag>-linux-amd64.cyclonedx.json | Backend Python runtime SBOM in CycloneDX JSON |
eneo-frontend-<release-tag>-linux-amd64.cyclonedx.json | Frontend image SBOM in CycloneDX JSON |
eneo-frontend-<release-tag>-linux-amd64.spdx.json | Frontend image SBOM in SPDX JSON |
eneo-frontend-<release-tag>-linux-amd64.table.txt | Frontend image package list for human review |
eneo-frontend-source-<release-tag>.cyclonedx.json | Frontend source dependency SBOM in CycloneDX JSON |
IMAGE-DIGESTS.txt | Exact image tags and digests that were scanned |
SBOM-SHA256SUMS.txt | SHA-256 checksums for the SBOM bundle |
Use the .table.txt files when you want to inspect a package list quickly. Use
CycloneDX or SPDX when you need to import an SBOM into another tool.
What the SBOM covers
The image SBOMs describe packages Syft finds inside the released container images.
For the backend image, this usually includes:
- operating system packages
- Python packages installed in the image
- binaries and other package metadata Syft can identify
For the frontend image, this usually includes:
- operating system packages
- npm packages still identifiable from the bundled runtime image
- binaries and other package metadata Syft can identify
The frontend source dependency SBOM is broader than the frontend image SBOM. It
is generated from the checked-out release tag after the workflow runs
bun install --frozen-lockfile against frontend/bun.lock. It can include
build-time dependencies that are not present as separate packages in the runtime
image.
The backend Python runtime SBOM is narrower. It is generated from the Python
environment installed at /app/.venv inside the released backend image. It is
validated during the workflow by checking that the Python distributions found
in that runtime environment appear in the generated CycloneDX file.
The SBOMs are generated from immutable image digest references, not only from
tags. IMAGE-DIGESTS.txt records the digest references used during the scan.
Which file should you use?
Use the backend or frontend CycloneDX JSON files when your tooling expects CycloneDX and you want the full container image inventory.
Use the SPDX JSON files when your process or supplier tooling expects SPDX.
Use eneo-backend-python-runtime-<release-tag>-linux-amd64.cyclonedx.json when
you want a focused view of the Python packages installed in the backend runtime
environment.
Use eneo-frontend-source-<release-tag>.cyclonedx.json when you want a focused
view of frontend JavaScript dependencies from the release source and lockfile.
Use the .table.txt files when you want to read the package list without
importing an SBOM into another tool.
Use IMAGE-DIGESTS.txt to see which GHCR image digests were scanned. Use
SBOM-SHA256SUMS.txt to check the downloaded SBOM files against the checksums
published with the release.
Use GitHub artifact attestations when you need cryptographic evidence that a release SBOM asset was generated by Eneo’s GitHub Actions workflow:
gh attestation verify ./eneo-backend-v2.0.0-linux-amd64.cyclonedx.json \
--repo eneo-ai/eneoThe backend and frontend container images also have provenance attestations in GitHub Container Registry:
gh attestation verify oci://ghcr.io/eneo-ai/eneo-backend:2.0.0 \
--repo eneo-ai/eneoIf an image package is private, verification follows normal GitHub and GHCR access rules. No separate identity provider is required to read or verify the SBOM.
What the SBOM does not cover
An SBOM is an inventory. It does not decide whether a package is vulnerable or whether a vulnerability is reachable in Eneo.
Use vulnerability scanners such as Grype, Trivy, GitHub Advanced Security, or your internal tooling if you need vulnerability findings based on the SBOM.
The attestations prove where the release SBOM assets and container images came from. They do not decide whether a dependency is vulnerable or whether a vulnerability is reachable in Eneo.
The current release workflow publishes linux/amd64 SBOM files. If Eneo adds
more release platforms later, each platform should get its own SBOM files
because package contents can differ by image architecture.
Standards and tools
These references explain the formats and tools used by Eneo:
- CycloneDX is the SBOM format used for the CycloneDX JSON release assets.
- OWASP SCVS SBOM requirements describe maturity expectations such as automated SBOM creation, machine-readable formats, metadata, and component inventory.
- Syft is used for the backend and frontend image SBOMs.
- CycloneDX Python is used for the backend Python runtime SBOM.
- CycloneDX Generator is used for the frontend source dependency SBOM.
- Anchore SBOM Action provides the GitHub Action helpers used to download Syft in the release workflow.
- SPDX is the other machine-readable SBOM format published for each image.
- GitHub artifact attestations provide cryptographic provenance for the release SBOM assets and container images.
- SLSA provenance describes where a built artifact came from and how it was produced.
Check a release
- Open the Eneo GitHub Releases page and choose the version you use.
- Download the backend and frontend
.table.txtfiles for a quick review. - Download CycloneDX or SPDX image SBOMs for your security tooling.
- Download the backend Python runtime SBOM if you only need the Python dependency inventory for the backend runtime environment.
- Download the frontend source dependency SBOM if you need the JavaScript dependency inventory from the release source and lockfile.
- Check
IMAGE-DIGESTS.txtif you need the exact image digests scanned. - Check
SBOM-SHA256SUMS.txtif you need file checksums for the SBOM bundle. - Use
gh attestation verifyif you need cryptographic provenance.
To compare two releases, compare the SBOM files from both release pages. Package additions, removals, and version changes show what changed between the images.