Skip to main content
CoreSDK
Reference

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.json

The 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.json

Downloading 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.json

Or fetch directly from the GitHub release:

gh release download v1.2.0 \
  --repo coresdk/coresdk \
  --pattern "*.sbom.json" \
  --dir ./sboms

CVE-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 check

Python: 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.json

Go: nancy

nancy audits Go modules against the OSS Index vulnerability database.

go list -json -deps ./... | nancy sleuth

CI 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.0

A 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 PracticeCoreSDK implementation
PO.1.1 — Identify and document software dependenciescargo-cyclonedx + syft SBOM generation on every release
PW.4.1 — Reuse existing, well-secured softwarecargo-deny license allowlist blocks unapproved licenses
PW.4.4 — Verify third-party software integritycosign image signatures + SBOM attestations on Docker images
RV.1.1 — Gather information about vulnerabilitiescargo-deny, pip-audit, nancy integrated in CI; weekly scheduled run
RV.1.2 — Review and analyse vulnerability reportsdeny.toml ignore list with required reason and expires fields
RV.2.1 — Remediate vulnerabilitiesCI 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

On this page