Skip to content

Supply-Chain Security

Opencomplai ships official container images with cryptographic signatures and software bill of materials (SBOM) attestations. This page covers how the signatures are produced and how you can verify them before deploying.

Check which images exist

Release images are built, signed and attested by supply-chain.yml in the release repository Opencomplai/opencomplai-enterprise when a vX.Y.Z tag passes the Trivy release gate, and pushed to ghcr.io/opencomplai/opencomplai-enterprise/<service>. You can pull and verify them only if the GHCR packages are public. Package visibility and the published tags are unverified at the time of writing: check the registry for the tags that actually exist and use one as <version> below.

How official images are signed

Every official image under ghcr.io/opencomplai/opencomplai-enterprise/<service> (the workflow lowercases the release repository name Opencomplai/opencomplai-enterprise to form the path) is built, signed, and attested by the supply-chain.yml GitHub Actions workflow in that release repository, whose runs are not public. The workflow runs on every version tag (v*.*.*) and on manual dispatch.

The signing uses cosign keyless mode, backed by the Sigstore public-good infrastructure (Rekor transparency log and Fulcio CA). No long-lived signing key is stored in CI. The signing identity is the workflow's OIDC token, scoped to the Opencomplai/opencomplai-enterprise repository and the supply-chain.yml workflow file.

The SBOM is generated by syft in SPDX-JSON format and attached to the image as a cosign in-toto attestation (--type spdxjson).

Verifying an image signature

Bash
cosign verify \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp "^https://github.com/Opencomplai/opencomplai-enterprise/\.github/workflows/supply-chain\.yml@" \
  ghcr.io/opencomplai/opencomplai-enterprise/gateway-api:<version>
PowerShell
cosign verify `
  --certificate-oidc-issuer https://token.actions.githubusercontent.com `
  --certificate-identity-regexp "^https://github.com/Opencomplai/opencomplai-enterprise/\.github/workflows/supply-chain\.yml@" `
  ghcr.io/opencomplai/opencomplai-enterprise/gateway-api:<version>

The command exits 0 and prints the signing certificate when the signature is valid and the identity matches the expected workflow.

Verifying the SBOM attestation

Use the helper script bundled with the repository:

Bash
./sync/verify-sbom.sh gateway-api:<version>
PowerShell
# Bash script — run via WSL2 or Git Bash
./sync/verify-sbom.sh gateway-api:<version>

It runs both cosign verify and cosign verify-attestation and decodes the predicate name from the SBOM payload. A full image reference (anything with a /) is used as is; set OPENCOMPLAI_RELEASE_REPO=<owner>/<repo> to check an image built by supply-chain.yml in another repository.

SBOM format

The SBOM is SPDX-JSON (SPDX 2.3). You can extract it from the attestation and pipe it into other tooling:

Bash
cosign download attestation \
  --predicate-type https://spdx.dev/Document \
  ghcr.io/opencomplai/opencomplai-enterprise/gateway-api:<version> \
  | jq -r '.payload | @base64d | fromjson | .predicate' > gateway-api.spdx.json
PowerShell
cosign download attestation `
  --predicate-type https://spdx.dev/Document `
  ghcr.io/opencomplai/opencomplai-enterprise/gateway-api:<version> `
  | jq -r '.payload | @base64d | fromjson | .predicate' > gateway-api.spdx.json

Scanning for known vulnerabilities

syft and grype compose cleanly:

Bash
syft ghcr.io/opencomplai/opencomplai-enterprise/gateway-api:<version> -o spdx-json \
  | grype --fail-on high
PowerShell
syft ghcr.io/opencomplai/opencomplai-enterprise/gateway-api:<version> -o spdx-json `
  | grype --fail-on high

CI runs an equivalent scan on every pull request via the vulnerability-scan job of the ci-docker.yml workflow in the release repository. CRITICAL and HIGH fixable findings fail the build.

That job scans all five service images — gateway-api, risk-engine, evidence-vault, doc-generator and egress-proxy. It previously covered only gateway-api, so the other four were signed and SBOM'd at release but never CVE-scanned: an SBOM records what is in an image, it does not say the contents are safe.

The same scan now also runs as a release gate in supply-chain.yml in the release repository, before the image is pushed or signed. Signing first would mean attesting an image nobody had checked.

Unfixable findings are excluded (ignore-unfixed). They cannot be acted on here, and a gate that cannot be made green is one people learn to route around.

The Trivy record, infra/docker/TRIVY-LAST-RUN.md, is a point-in-time record of the release gate's scan on the five images. It is not a guarantee that the images are clean today. Refresh it by re-running the build and scan commands recorded in the file whenever the pinned Trivy version or a FROM base digest changes; test_docker_images_hardening.py fails until it matches.

Python packages

PyPI releases are published with Trusted Publishing (OIDC), with no API token and no long-lived secret. Every distribution carries PEP 740 attestations, generated at upload and shown on the file's PyPI page.

SLSA build provenance is not attested: GitHub's artifact attestations are not available for the private release repository on the current billing plan.

The release workflow, publish-pypi.yml, checks the tag against the package versions, runs the wheel smoke test and generates a CycloneDX SBOM per package before anything is uploaded. Those SBOMs are build artifacts of the workflow run; they are not uploaded to PyPI or to the GitHub Release.