3.3 KiB
3.3 KiB
Promotion Evidence Contract
Purpose
This contract defines the evidence payload that promotion gates consume. It freezes ownership boundaries and required fields for deterministic and offline-capable release decisions.
Ownership Boundaries
| Capability | Owning module | Notes |
|---|---|---|
| Evidence storage and retrieval | EvidenceLocker | Stores immutable evidence; does not decide allow/deny. |
| DSSE signing | Signer | Produces signed envelopes and signer metadata. |
| Transparency logging and proof material | Attestor | Produces Rekor UUID/log index/proof references and verifies proofs. |
| PASS/FAIL policy decisioning | Policy Engine | Evaluates gate logic and emits decision outputs. |
| Promotion orchestration | Release Orchestrator | Consumes evidence + policy outputs to progress promotion state. |
Canonical Promotion Gate Input
The promotion gate input MUST be serializable as canonical JSON with stable key order and UTC timestamps.
{
"artifact": {
"artifactId": "string",
"digest": "sha256:..."
},
"evidence": {
"evidenceScore": "lowercase-hex-sha256",
"bundleId": "guid",
"bundleDigest": "sha256:..."
},
"sbom": {
"canonicalDigest": "sha256:...",
"format": "cyclonedx|spdx"
},
"attestations": [
{
"predicateType": "string",
"dsseDigest": "sha256:...",
"signerKeyId": "string"
}
],
"transparency": {
"rekorUuid": "string",
"logIndex": 0,
"proofRef": "cas://..."
},
"vex": {
"mergedDigest": "sha256:...",
"statusSummary": "affected|not_affected|under_investigation|mixed"
},
"inToto": {
"layoutDigest": "sha256:...",
"linkDigests": ["sha256:..."]
}
}
EvidenceLocker API Mapping
| Endpoint | Contract fields populated |
|---|---|
POST /evidence |
artifact.*, evidence.evidenceScore |
GET /evidence/score?artifact_id=... |
evidence.evidenceScore |
POST /evidence/snapshot |
evidence.bundleId, evidence.bundleDigest |
GET /evidence/{bundleId} |
sbom.*, attestations[], vex.*, inToto.* |
POST /evidence/verify |
transparency.* verification status and proof linkage |
GET /evidence/{bundleId}/portable |
Offline bundle material for air-gapped verification |
Determinism Requirements
- Serialize gate input with stable ordering and invariant casing.
- Use UTC RFC3339 timestamps only.
- Sort all arrays that do not carry semantic order by deterministic key:
attestations[]bypredicateType, thendsseDigestinToto.linkDigests[]lexicographically
- Treat digest values as lowercase.
- Fail closed if required evidence fields are missing.
Offline Verification Requirements
- Promotion gates MUST accept proof references from offline bundles.
- Rekor verification may use tile/proof material from local mirrors.
- If transparency data is unavailable, gate outcome must be explicit policy output (for example deny, or break-glass path with auditable reason).
Implementation References
- EvidenceLocker architecture:
docs/modules/evidence-locker/architecture.md - EvidenceLocker attestation contract:
docs/modules/evidence-locker/attestation-contract.md - Policy ownership contract:
docs/modules/policy/promotion-gate-ownership-contract.md - Release Orchestrator runtime gap plan:
docs/modules/release-jobengine/promotion-runtime-gap-closure-plan.md