Promotion-Time Attestations for Stella Ops
Destination currency (source-verified 2026-10-07 at
f9dbf896333339ed6ed3e655d4e8e3a793cc38fe): Evidence hosts attestation, canonical-record, capsule, and signing-key reads under/api/evidence/v1; OfflineKit hosts the standard export API under/api/offlinekit/v1/exports. The owner handler suffix determines the complete path. See Evidence architecture. This documentation update does not verify a live signing, promotion, or export operation.
Status: Stable (2025-11)
Owners: Signing Guild · Provenance Guild · DevEx/CLI Guild · Export Center Guild
1. Purpose
Capture the full promotion-time evidence – image digest, SBOM/VEX artifacts, Rekor proof – in a single DSSE-wrapped statement so that air-gapped auditors can verify releases without talking to external services. This document explains the data shape, producer responsibilities, and downstream consumers that rely on the promotion attestation.
2. Predicate schema – stella.ops/promotion@v1
{
"_type": "stella.ops/promotion@v1",
"subject": [
{ "name": "registry.example.com/acme/api", "digest": { "sha256": "…" } }
],
"materials": [
{ "role": "sbom", "algo": "sha256", "digest": "…", "format": "CycloneDX-1.6", "uri": "oci://…/sbom@sha256:…" },
{ "role": "vex", "algo": "sha256", "digest": "…", "format": "OpenVEX-1.0", "uri": "oci://…/vex@sha256:…" }
],
"promotion": {
"from": "staging",
"to": "prod",
"actor": "ci/gitlab-runner",
"timestamp": "2025-11-10T12:34:56Z",
"pipeline": "https://git.example.com/acme/api/-/pipelines/12345",
"ticket": "JIRA-1234",
"notes": "risk accepted by ops"
},
"rekor": {
"uuid": "REKOR_ENTRY_UUID",
"logIndex": 1234567,
"inclusionProof": {
"rootHash": "MERKLE_ROOT",
"hashes": ["…path…"],
"treeSize": 9876543,
"checkpoint": {
"origin": "rekor.sigstore.dev - transparency log",
"size": 9876543,
"hash": "CHECKPOINT_HASH",
"signedNote": "BASE64_NOTE"
}
}
},
"attestation": {
"bundle_sha256": "sha256:…",
"witness": "optional-transparency-witness-signature"
}
}
The Provenance Guild implements the predicate builder (task PROV-OBS-53-003). The signer pipeline accepts the predicate as a raw JSON payload and wraps it inside a DSSE envelope (SIGN-CORE-186-005). Rekor metadata is pulled from Attestor after DSSE submission.
3. Producer workflow
3.1 CLI orchestration (CLI-PROMO-70-001/002)
- Resolve and freeze the image digest (
cosign triangulate/crane digest). - Hash SBOM and VEX artifacts, optionally publish them to an OCI registry.
- Upload the SBOM (or dummy artifact) to Rekor to obtain
{uuid, logIndex}. - Retrieve inclusion proof + checkpoint (
rekor-cli get,rekor-cli loginfo). - Build
attestation.jsonusing the template above and current promotion metadata. - Call Signer to produce a DSSE bundle (
cosign attestorstella promotion attest). - Store the bundle alongside
attestation.jsonand add both to Offline/Replay kits. - Emit Timeline + Evidence Locker entries with bundle digest.
3.2 Signer responsibilities (SIGN-CORE-186-004/005/006)
- Accept the promotion predicate, verify Proof-of-Entitlement + release integrity.
- Sign via StellaOps.Cryptography providers (keyless or KMS) and return DSSE+cert bundle.
- Emit audit entries referencing the promotion metadata and Rekor proof.
3.3 Export Center integration (EXPORT-OBS-54-002)
- Bundle
attestation.json, DSSE envelope, and Rekor checkpoint inside Offline kits. - Surface promotion evidence via API/CLI for air-gapped consumers.
4. Verification flow
Auditors can validate the promotion attestation offline:
- Verify the DSSE signature using the provided bundle and trusted key/cert chain.
- Recompute Merkle inclusion using the embedded proof + checkpoint. The checkpoint’s signed note ties the inclusion to a known Rekor tree size.
- Hash SBOM/VEX artifacts and compare to the
materialsdigests. - Confirm the promotion metadata in release notes/CI evidence.
Authority exposes helper APIs (AUTH-VERIFY-186-007) to replay both DSSE and Merkle validations.
5. APIs & storage
| Component | Endpoint / Artifact | Notes |
|---|---|---|
| Signer | POST /api/v1/signer/sign/dsse | Accepts promotion predicate, returns DSSE bundle + auditId. |
| Attestor | POST /api/evidence/v1/rekor/entries | Persists DSSE, returns {uuid, index, proof}. |
| OfflineKit | Promotion assembly reads under /api/offlinekit/v1/promotions | Current source contract listed below; no deployed acceptance is implied. |
| Evidence Locker | Store DSSE + Rekor proof for long-term retention. |
Current promotion assembly reads (source-verified 2026-10-07)
OfflineKit’s host mounts PromotionAttestationEndpoints on /api/offlinekit; the endpoint group adds /v1/promotions. Its current read contracts are:
GET /api/offlinekit/v1/promotions/attestations/{assemblyId}— assembly detail.GET /api/offlinekit/v1/promotions/{promotionId}/attestations— assemblies for the promotion.GET /api/offlinekit/v1/promotions/attestations/{assemblyId}/bundle— assembly bundle download.
The group requires ExportOperator, the catalog export.operator policy, including for these reads. These source-mapped operations do not establish a current deployment, generated artifact or verified promotion attestation. Re-verify src/OfflineKit/__Libraries/StellaOps.ExportCenter.Application/Attestation/PromotionAttestationEndpoints.cs and the host’s Program.cs together.
Historical 2025-11 export proposal
The former planned GET /api/v1/exports/{id}/promotion described a proposed promotion export. It does not identify a current mapped owner contract and is withdrawn as an implementation instruction. Use the distinct source-mapped promotion assembly reads above rather than replacing the proposal’s prefix.
Artifacts are content-addressed via CAS and mirrored into Offline kits (docs/replay/DETERMINISTIC_REPLAY.md).
6. Security considerations
- Promotion metadata is tenant-scoped; aim to avoid leaking pipeline URLs across tenants.
- Rekor inclusion proofs must be fetched at promotion time and embedded; do not rely on on-demand Rekor access in air-gapped installs.
- Rotate signing keys via Authority/KMS; promotion attestation inherits Signer’s DSSE trust model.
7. Implementation checklist
| Area | Sprint task | Status |
|---|---|---|
| Predicate builder | PROV-OBS-53-003 | Planned |
| Signer support | SIGN-CORE-186-004/005/006 | Planned |
| CLI commands | CLI-PROMO-70-001/002 | Planned |
| Authority verifier | AUTH-VERIFY-186-007 | Planned |
| Export packaging | EXPORT-OBS-54-002 | Planned |
| Documentation | DOCS-PROMO-70-001 | DONE (2025-11-26) |
When all tasks are completed this document should be updated with status links and sample payloads.
