Developer supply-chain guide¶
This guide documents the SBOM/provenance/signing architecture for contributors.
Design rule¶
Supply-chain evidence is release/control-plane logic. Do not put supply-chain business logic into command modules, runtime sinks, or connector code.
Module taxonomy¶
| Module | Responsibility |
|---|---|
dpone.supply_chain.pyproject_reader |
Read project metadata and dependency declarations. |
dpone.supply_chain.sbom |
Build SPDX-like and CycloneDX-like SBOM JSON documents. |
dpone.supply_chain.provenance |
Build in-toto/SLSA-inspired provenance JSON. |
dpone.supply_chain.signing |
Build local HMAC signature envelopes. |
dpone.supply_chain.attestation |
Orchestrate all artifacts into one bundle. |
dpone.commands.supply_chain_cmd |
Thin CLI adapter only. |
Class map¶
classDiagram
class PyprojectMetadataReader {
+read(project_root)
}
class SBOMService {
+build(project_root, output_dir)
}
class ProvenanceService {
+build(output_dir, release, subjects, repository, commit_sha, builder_id)
}
class LocalHMACSignatureService {
+sign_file(path, output_dir, key, key_id)
}
class SupplyChainAttestationService {
+build(...)
}
class supply_chain_cmd {
+cmd_supply_chain_attest(args, ctx, logger)
}
SBOMService --> PyprojectMetadataReader
SupplyChainAttestationService --> SBOMService
SupplyChainAttestationService --> ProvenanceService
SupplyChainAttestationService --> LocalHMACSignatureService
supply_chain_cmd --> SupplyChainAttestationService
Extension rules¶
- Add new SBOM formats as separate renderer/service classes.
- Add cloud/KMS/Sigstore signing as optional adapters, not as required core dependencies.
- Keep artifact JSON deterministic enough for CI diffing.
- Never write signing keys into output artifacts.
- Keep command modules argument-only; test business logic through services.
Test requirements¶
Every supply-chain change must include:
- service tests for generated SBOM/provenance/signature files;
- CLI tests for
dpone supply-chain attest; - docs contract tests for user docs, developer docs, architecture, and CI/CD;
- package build and lockfile-backed
uv run twine check dist/*when release metadata changes.
CI/CD contract¶
Generated artifacts belong under:
Upload them with if: always() on release and manual certification workflows.
Do not require external signing services for the default PR gate.
Release distributions also receive GitHub Artifact Attestations in
.github/workflows/release.yml before PyPI publishing. The release job must keep
id-token: write and attestations: write, and the attestation step must cover
both dist/*.whl and dist/*.tar.gz subjects.
After generating GitHub attestations, the release job verifies each wheel and
sdist with gh attestation verify scoped to the current repository, Git ref, and
commit SHA. Upload the JSON receipts from
test_artifacts/supply-chain/github-attestations/ with if: always() so failed
release attempts still leave diagnosable evidence.
Keep third-party workflow actions pinned to full commit SHAs and keep
astral-sh/setup-uv on an explicit version. Refresh action pins and the
uv runtime version intentionally in a reviewed PR instead of floating on tags,
branches, or the latest available toolchain.
Keep SLSA release self-assessment current when changing release provenance, attestation verification, artifact upload paths, Scorecard evidence, or the release publication order. The self-assessment is a scoped release claim, not a blanket guarantee for local builds or historical artifacts.