CI/CD Integration
A manually maintained SBOM is outdated the moment you create it. The multi-arch Docker image (amd64/arm64) drops kunnus into any pipeline so every release ships with a current SBOM.
GitHub Actions
.github/workflows/sbom.yml
- name: Generate SBOM
run: |
docker run --rm -v ${{ github.workspace }}:/src \
ghcr.io/think-ahead-technologies/kunnus-scanner:latest \
sbom repo /src --output /src/sbom.cdx.json
- name: Upload to kunnus platform
env:
KUNNUS_API_KEY: ${{ secrets.KUNNUS_API_KEY }}
KUNNUS_COMPONENT_ID: ${{ vars.KUNNUS_COMPONENT_ID }}
run: |
docker run --rm -v ${{ github.workspace }}:/src \
-e KUNNUS_API_KEY -e KUNNUS_COMPONENT_ID \
ghcr.io/think-ahead-technologies/kunnus-scanner:latest \
upload /src/sbom.cdx.jsonGitLab CI
.gitlab-ci.yml
sbom:
image:
name: ghcr.io/think-ahead-technologies/kunnus-scanner:latest
entrypoint: [""]
script:
- /kunnus sbom repo . --output sbom.cdx.json
- /kunnus upload sbom.cdx.json
variables:
KUNNUS_API_KEY: $KUNNUS_API_KEY
KUNNUS_COMPONENT_ID: $KUNNUS_COMPONENT_ID
artifacts:
paths: [sbom.cdx.json]Exit codes: complete vs. degraded SBOMs
Exit 0 means every extractor ran clean. If the scan finishes but some plugins failed, the SBOM is still written and kunnus exits 1 with a summary of the failed plugins — so a pipeline can tell a complete SBOM from one with gaps instead of silently shipping the latter. Re-run with --verbosity info (or KUNNUS_VERBOSITY=info) for per-plugin detail.
Upload configuration
kunnus upload reads its flags from environment variables — KUNNUS_API_KEY (required), KUNNUS_COMPONENT_ID, and KUNNUS_UPLOAD_URL — which is the natural fit for CI secrets. The server response is printed to stdout.
Supply-chain hardening: release images are signed with cosign and carry SLSA Build L3 provenance. Pin the image by digest and verify it — SECURITY.md in the repository shows how.