Supply-chain evidence¶
dpone supply-chain attest creates release evidence for OSS and internal CI:
- SPDX-like SBOM JSON;
- CycloneDX-like SBOM JSON;
- SLSA/in-toto-inspired provenance JSON;
- optional local HMAC signature envelope;
- one attestation bundle with checksums.
This command is dependency-light and works without external signing services. For public releases, the release workflow pairs it with GitHub Artifact Attestations and verifies the GitHub attestation receipts before publishing. The scoped release posture is documented in SLSA release self-assessment.
Contents¶
Quickstart¶
uv build
subjects=()
for artifact in dist/*.whl dist/*.tar.gz; do
subjects+=(--subject "$artifact")
done
uv run dpone supply-chain attest \
--project-root . \
--output-dir test_artifacts/supply-chain/current \
--release vX.Y.Z \
"${subjects[@]}" \
--repository https://github.com/PaulKov/dpone \
--commit-sha "$GITHUB_SHA" \
--builder-id "github-actions:$GITHUB_RUN_ID" \
--signing-key "$DPONE_LOCAL_ATTESTATION_KEY" \
--signing-key-id github-actions \
--format json
Artifacts¶
| File | Purpose |
|---|---|
sbom.spdx.json |
SPDX-like dependency inventory generated from pyproject.toml. |
sbom.cyclonedx.json |
CycloneDX-like component inventory generated from pyproject.toml. |
provenance.intoto.json |
Release subjects, SHA-256 digests, repo, commit, builder, and release metadata. |
signature.hmac-sha256.json |
Local HMAC signature envelope for deterministic CI evidence. |
supply_chain_attestation.json |
Bundle index with artifact paths and checksums. |
supply_chain_attestation.md |
Human-readable release evidence summary. |
Signing model¶
The built-in signature is a local HMAC-SHA256 envelope. It proves that the same CI environment with access to the same secret signed a specific provenance digest. It is useful for internal evidence chains and deterministic testing.
It is not a public identity replacement for:
- GitHub artifact attestations;
- Sigstore/cosign;
- hardware-backed code signing;
- cloud KMS signing.
Use external identity-backed signing for public release trust, and attach the dpone bundle as additional evidence.
CI pattern¶
Recommended release job order:
uv sync --all-extras
uv run pytest -m "not integration_live"
uv build
uv run twine check dist/*
subjects=()
for artifact in dist/*.whl dist/*.tar.gz; do
subjects+=(--subject "$artifact")
done
uv run dpone supply-chain attest \
--release "$GITHUB_REF_NAME" \
"${subjects[@]}" \
--repository "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" \
--commit-sha "$GITHUB_SHA" \
--builder-id "github-actions:$GITHUB_RUN_ID" \
--signing-key "$DPONE_LOCAL_ATTESTATION_KEY" \
--signing-key-id github-actions \
--output-dir test_artifacts/supply-chain/current \
--format json
mkdir -p test_artifacts/supply-chain/github-attestations
for artifact in dist/*.whl dist/*.tar.gz; do
gh attestation verify "$artifact" \
--repo "$GITHUB_REPOSITORY" \
--source-ref "$GITHUB_REF" \
--source-digest "$GITHUB_SHA" \
--format json \
> "test_artifacts/supply-chain/github-attestations/$(basename "$artifact").github-attestation.json"
done
Set DPONE_LOCAL_ATTESTATION_KEY as a release environment secret. Upload
test_artifacts/supply-chain/current/ and
test_artifacts/supply-chain/github-attestations/ as release evidence
artifacts. PyPI publication must stay after the GitHub verification step.
Runbook¶
| Symptom | Likely cause | Action |
|---|---|---|
subjects.empty |
No --subject files were provided. |
Run uv build first and pass wheel/sdist paths. |
subject.missing.<path> |
A subject path does not exist. | Check glob expansion and working directory in CI. |
signature.missing_key |
No local signing key was provided. | Set DPONE_LOCAL_ATTESTATION_KEY or run external Sigstore/GitHub attestation separately. |
gh attestation verify fails |
GitHub attestation has not propagated, the artifact digest changed, or the source repo/ref/digest does not match. | Re-run the release job after propagation. If it still fails, rebuild from the tagged commit and do not publish the mismatched artifacts. |
| SBOM misses a dependency | Dependency is not declared in pyproject.toml. |
Add dependency metadata or extend the SBOM reader for lockfile evidence. |
| Public users cannot verify trust | HMAC is local-only evidence. | Add GitHub artifact attestation or Sigstore/cosign in the release workflow. |