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
- name: Generate SBOM
env:
# Keys the SBOM's serialNumber, so successive pipeline runs form one
# document series instead of unrelated documents.
KUNNUS_COMPONENT_ID: ${{ vars.KUNNUS_COMPONENT_ID }}
KUNNUS_COMPONENT_VERSION: ${{ github.ref_name }}
# Records your organization as the SBOM author (CISA minimum element).
KUNNUS_AUTHOR: ${{ vars.KUNNUS_AUTHOR }}
run: |
docker run --rm -v ${{ github.workspace }}:/src \
-e KUNNUS_COMPONENT_ID -e KUNNUS_COMPONENT_VERSION -e KUNNUS_AUTHOR \
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.jsonThe three identity variables are what turns a pile of per-run SBOMs into a document series an auditor can follow: KUNNUS_COMPONENT_ID keys the serial number, KUNNUS_COMPONENT_VERSION names the release, and KUNNUS_AUTHOR records who operated the scanner. Use the same component id you use for kunnus upload. Without them the scan still succeeds — every run just gets a random serial and a placeholder author.
GitLab CI
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
KUNNUS_COMPONENT_VERSION: $CI_COMMIT_REF_NAME
KUNNUS_AUTHOR: $KUNNUS_AUTHOR
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.
gh attestation verify — SECURITY.md in the repository shows how.