CI/CD integration
The target pipeline
1. build → produces the artefact
2. sbom-generate → build SBOM + analysed SBOM
3. sbom-validate → schema, quality score, build/analysed gap
↳ FAIL below threshold
4. sbom-sign → signature + provenance attestation
5. sbom-publish → send to the steering platform
6. policy-gate → vulnerabilities, licences, VEX
↳ FAIL or WARN depending on policy
7. attach → SBOM and signature attached to the artefact in the registry
8. archive → deposited in the evidence vault, indexed by hash
Steps 3 and 6 are blocking. The others are production steps: their failure must also fail the build, or artefacts without an SBOM will reach production.
Example — GitHub Actions
jobs:
build-and-attest:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # keyless signing, no long-lived secret
packages: write
steps:
- uses: actions/checkout@v4
- name: Build the artefact
run: make build
- name: Generate the SBOM (build)
run: syft dir:. -o cyclonedx-json=sbom-build.cdx.json
- name: Generate the SBOM (analysed)
run: syft "$IMAGE" -o cyclonedx-json=sbom-analyzed.cdx.json
- name: Validate quality and gap
run: ./ci/validate-sbom.sh sbom-build.cdx.json sbom-analyzed.cdx.json
- name: Sign
run: cosign attest --predicate sbom-build.cdx.json --type cyclonedx "$IMAGE"
- name: Publish to the platform
run: ./ci/publish-sbom.sh sbom-build.cdx.json
- name: Policy gate (vulnerabilities and licences)
run: ./ci/policy-gate.sh sbom-build.cdx.json
The principle is the same on GitLab CI, Jenkins or Azure DevOps: the steps are identical, only
the syntax changes. The validate-sbom.sh, publish-sbom.sh and policy-gate.sh scripts are
shared across all chains and versioned in a central repository — that is what makes
thresholds uniform.
The blocking rules
| Condition | Effect | Rationale |
|---|---|---|
| SBOM not generated or schema invalid | Fail | Without an SBOM there is no possible compliance |
| Quality score below threshold | Fail | An incomplete SBOM gives false assurance |
| Build / analysed gap above threshold | Fail | Reveals undeclared code |
| Critical exploitable vulnerability, no VEX | Fail | Annex I: no known exploitable vulnerability at placing on the market |
| High-severity vulnerability, no VEX | Warning + ticket | Handled within the SLA |
| Licence on the deny list for this context | Fail | Licence policy |
| Licence on the review list | Warning + ticket | Legal review |
| Signature or attestation missing | Fail | Without a signature, the SBOM is not evidence |
Waivers
A block with no escape hatch gets bypassed, usually by disabling the check. A controlled waiver is therefore needed:
- requested through a ticket, with justification;
- granted by a named person — the CISO for vulnerabilities, Legal for licences;
- time-limited, with a mandatory expiry date;
- recorded in a versioned file alongside the code, readable by the pipeline;
- automatically expired: on the date, the block resumes.
A permanent waiver is a change to the policy, and must be treated as one — not as an exception.
Special cases
Monorepos. One SBOM per publishable artefact, not one per repository. The difficulty is attributing shared dependencies correctly; native build-chain plugins handle this better than generic generators.
Matrix builds. One artefact per OS or architecture combination, therefore one SBOM per combination. One variant’s SBOM does not hold for the others.
Incremental builds and caching. Caching can mask a dependency change. The SBOM must be regenerated for every publishable build, with no cache reuse.
Repackaged third-party artefacts. If you republish an artefact you did not build, you must analyse it — the supplier’s SBOM, where it exists, is a starting point to verify, not a document to adopt as is.
The cost
Generation adds anywhere from seconds to minutes per build, depending on artefact size and method. The usual levers:
- produce the analysed SBOM only on publishable builds, not on every pull request;
- cache the tools’ vulnerability databases, not the results;
- parallelise generation with the test suite;
- reserve the full cross-check for release branches.
None of these optimisations may reduce what is produced for a shipped artefact: that is the only case where compliance is at stake.