SBOM & Dependency Audit
Software Bill of Materials generation, CVE-aware dependency auditing, and cosign/sigstore image signing for CoreSDK releases.
SBOM & Dependency Audit
CoreSDK generates a Software Bill of Materials (SBOM) for every release and provides first-class CI tooling to audit your own dependency tree for known vulnerabilities. All Docker images are signed with cosign and carry an attached SBOM attestation. This page describes the toolchain, CI integration, and configuration options.
SBOM generation
Rust workspace (cargo-cyclonedx)
The CoreSDK Rust workspace uses cargo-cyclonedx to generate CycloneDX 1.5 SBOMs covering all crates in the workspace, including transitive dependencies.
# Generate SBOM for the entire workspace
cargo cyclonedx --format json --output coresdk-sbom.json
# Generate SBOM for a single crate
cargo cyclonedx --format json --package coresdk-engine --output coresdk-engine-sbom.jsonThe generated SBOM includes:
- Component name, version, and package URL (PURL).
- License expression per component.
- Dependency graph (component relationships).
- Hashes (SHA-256) for each compiled artifact.
Python, Go, and TypeScript SDKs (syft)
The wrapper SDKs use syft for SBOM generation. syft produces CycloneDX or SPDX output and handles language-specific package manifests (pyproject.toml, go.sum, package-lock.json).
# Python SDK
syft packages ./sdk/python --output cyclonedx-json=coresdk-python-sbom.json
# Go SDK
syft packages ./sdk/go --output cyclonedx-json=coresdk-go-sbom.json
# TypeScript SDK
syft packages ./sdk/typescript --output cyclonedx-json=coresdk-ts-sbom.json
# Docker image
syft packages coresdk/sidecar:1.2.0 --output cyclonedx-json=coresdk-sidecar-sbom.jsonDownloading release SBOMs
Every CoreSDK release publishes SBOMs as GitHub release assets. Download via the CLI:
core sbom download --version 1.2.0 --format cyclonedx --output coresdk-1.2.0.sbom.json
core sbom download --version 1.2.0 --format spdx --output coresdk-1.2.0.spdx.jsonOr fetch directly from the GitHub release:
gh release download v1.2.0 \
--repo coresdk/coresdk \
--pattern "*.sbom.json" \
--dir ./sbomsCVE-aware dependency audit
Rust: cargo-deny
cargo-deny audits the Rust dependency graph against the RustSec Advisory Database. It also enforces license allowlists and detects duplicate dependency versions.
# deny.toml
[advisories]
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
vulnerability = "deny"
unmaintained = "warn"
yanked = "deny"
notice = "warn"
ignore = [
# Example: "RUSTSEC-2023-0071",
]
[licenses]
unlicensed = "deny"
allow = [
"MIT",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"Unicode-DFS-2016",
]
deny = [
"GPL-2.0",
"GPL-3.0",
"AGPL-3.0",
]
copyleft = "warn"
[bans]
multiple-versions = "warn"
deny = [
# Ensure OpenSSL never enters the dependency tree
{ name = "openssl" },
{ name = "openssl-sys" },
]
[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]Run the audit locally:
cargo deny checkPython: pip-audit
pip-audit audits Python dependencies against the PyPI Advisory Database and the OSV database.
pip install pip-audit
pip-audit --requirement requirements.txt --output json --output-file audit-report.jsonGo: nancy
nancy audits Go modules against the OSS Index vulnerability database.
go list -json -deps ./... | nancy sleuthCI integration
The following GitHub Actions workflow runs the full audit suite on every push and pull request. The job fails if any vulnerability at HIGH severity or above is found in any language layer.
name: Dependency Audit
on:
push:
branches: [main, develop]
pull_request:
schedule:
- cron: "0 6 * * 1" # weekly Monday audit for newly published advisories
jobs:
audit-rust:
name: Rust (cargo-deny)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-deny
run: cargo install cargo-deny --locked
- name: Run cargo deny
run: cargo deny check
audit-python:
name: Python (pip-audit)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install pip-audit
run: pip install pip-audit
- name: Audit Python SDK
run: |
pip-audit \
--requirement sdk/python/requirements.txt \
--output json \
--output-file pip-audit-report.json
# Fail on HIGH or CRITICAL
pip-audit \
--requirement sdk/python/requirements.txt \
--severity high
- name: Upload audit report
if: always()
uses: actions/upload-artifact@v4
with:
name: pip-audit-report
path: pip-audit-report.json
audit-go:
name: Go (nancy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
- name: Install nancy
run: go install github.com/sonatype-nexus-community/nancy@latest
- name: Audit Go SDK
working-directory: sdk/go
run: go list -json -deps ./... | nancy sleuth
generate-sbom:
name: Generate and upload SBOM
runs-on: ubuntu-latest
needs: [audit-rust, audit-python, audit-go]
steps:
- uses: actions/checkout@v4
- name: Install cargo-cyclonedx
run: cargo install cargo-cyclonedx --locked
- name: Install syft
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \
| sh -s -- -b /usr/local/bin
- name: Generate Rust SBOM
run: cargo cyclonedx --format json --output coresdk-rust.sbom.json
- name: Generate Python SBOM
run: syft packages sdk/python --output cyclonedx-json=coresdk-python.sbom.json
- name: Generate Go SBOM
run: syft packages sdk/go --output cyclonedx-json=coresdk-go.sbom.json
- name: Upload SBOMs
uses: actions/upload-artifact@v4
with:
name: sboms
path: "*.sbom.json"cosign image signing and SBOM attestation
All CoreSDK Docker images published to the container registry are signed with cosign using keyless signing via Sigstore's public Rekor transparency log. An SBOM attestation is attached to each image digest.
Verifying an image signature
cosign verify \
--certificate-identity "https://github.com/coresdk/coresdk/.github/workflows/release.yml@refs/heads/main" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
coresdk/sidecar:1.2.0A successful verification confirms that the image was built by the CoreSDK CI pipeline and has not been tampered with since signing.
Verifying the SBOM attestation
cosign verify-attestation \
--type cyclonedx \
--certificate-identity "https://github.com/coresdk/coresdk/.github/workflows/release.yml@refs/heads/main" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
coresdk/sidecar:1.2.0 \
| jq '.payload | @base64d | fromjson | .predicate'This extracts the CycloneDX SBOM embedded in the attestation. The output is the same SBOM that is available as a release asset, allowing you to verify that the release asset has not been substituted.
Signing in the release pipeline
The CI release workflow signs images and attaches attestations automatically:
- name: Sign image
run: |
cosign sign --yes \
coresdk/sidecar@${{ steps.build.outputs.digest }}
- name: Attach SBOM attestation
run: |
cosign attest --yes \
--predicate coresdk-sidecar.sbom.json \
--type cyclonedx \
coresdk/sidecar@${{ steps.build.outputs.digest }}NIST SSDF alignment
The toolchain described on this page maps to practices in the NIST Secure Software Development Framework (SSDF) SP 800-218:
| SSDF Practice | CoreSDK implementation |
|---|---|
| PO.1.1 — Identify and document software dependencies | cargo-cyclonedx + syft SBOM generation on every release |
| PW.4.1 — Reuse existing, well-secured software | cargo-deny license allowlist blocks unapproved licenses |
| PW.4.4 — Verify third-party software integrity | cosign image signatures + SBOM attestations on Docker images |
| RV.1.1 — Gather information about vulnerabilities | cargo-deny, pip-audit, nancy integrated in CI; weekly scheduled run |
| RV.1.2 — Review and analyse vulnerability reports | deny.toml ignore list with required reason and expires fields |
| RV.2.1 — Remediate vulnerabilities | CI gate blocks merge on HIGH/CRITICAL findings |
Ignoring known false positives
For vulnerabilities that do not apply to your use of a dependency, add an ignore entry with a mandatory reason and expiry date:
# deny.toml — Rust
[advisories]
ignore = [
{ id = "RUSTSEC-2023-0071", reason = "We do not use the affected RSA padding mode" },
]# .pip-audit-ignore.yaml — Python
ignore:
- id: PYSEC-2024-00123
reason: "Vulnerability is in the CLI entrypoint; we use only the library API"
expires: "2026-09-01"Ignore entries without an expires date generate a warning in CI output to prompt periodic review. Entries that have passed their expiry date cause the audit to fail, forcing a conscious renewal decision.
Next steps
- Compliance Controls — how SBOMs support SOC 2 and PCI DSS assessments
- Security Hooks — runtime enforcement hooks
- Roadmap — upcoming SBOM features and SLSA Level 3 provenance