Files
git.stella-ops.org/docs/modules/evidence-locker/attestation-contract.md

4.6 KiB

Evidence Locker Attestation Contract (v1 · frozen 2025-11-20)

Scope: Evidence Bundle v1 produced by Evidence Locker and consumed by Concelier, Excititor, Export Center, CLI, and Policy Engine.

Predicates & subjects

  • Subject (mandatory): Merkle root derived from checksums.txt (sha256 of the sorted file) for the sealed bundle. OCI digest of the tarball remains recorded as bundle_oci_digest inside the predicate for registry mirroring but is not the DSSE subject.
  • Predicates (DSSE/In-Toto)
    • stellaops.evidence.bundle.v1: declares bundle layout (manifests, CAS paths, replay log offsets, Merkle recipe, chunking strategy).
    • stellaops.evidence.transparency.v1: Rekor/log inclusion proof (UUID, log index, root hash at inclusion). Required when network-permitted; when offline, include reason="offline" and omit log pointers.
    • stellaops.evidence.integrity.v1: hashes for each payload (SBOMs, VEX, policy packs, telemetry snapshots), keyed by canonical path; must match entries in bundle.manifest.schema.json.

Required claim set

  • bundle_id (UUID v4)
  • produced_at (UTC ISO-8601)
  • producer (evidence-locker:<region>)
  • subject_merkle_root (sha256 from checksums.txt)
  • hashes (map: canonicalPath → sha256) sorted lexicographically
  • sbom (array of SPDX/CycloneDX digests and mediaTypes)
  • vex (array of VEX doc digests and schema versions)
  • replay_manifest (optional; digest + sequence number, ledger URI, dsseEnvelope)
  • transparency (optional; Rekor UUID, logIndex, rootHash, inclusionProof) or reason="offline"
  • signing_profile (sovereign-default | fips | gost | pq-experimental)

Bundling & signing rules

  • DSSE envelope is mandatory for every sealed bundle using the configured ICryptoProviderRegistry profile; keys must be short-lived (<24h) and recorded in provider registry.
  • Subject = sha256(Merkle root) from checksums.txt; verifier must recompute to match.
  • Hash list must match bundle.manifest.schema.json (entries + optional hashSummary), sorted by canonicalPath.
  • Rekor/logging policy:
    • If outbound log is allowed, submit to configured log and embed UUID/logIndex/rootHash in transparency.
    • If outbound log is disallowed/offline, set transparency to null and include reason="offline" plus log_policy="skip" inside the predicate.

Verification plan

  • Verify DSSE signature against provider registry (per profile) and check key expiry.
  • Recompute sha256 for every manifest entry and the Merkle root; fail if subject differs.
  • If transparency present, verify inclusion proof against bundled Rekor root; fail closed on mismatch. If absent, require reason="offline" and log_policy="skip".
  • Emit verification report JSON (deterministic key order) and store beside bundle as verify.json.

Fixtures

  • Sample bundle + report: docs/modules/evidence-locker/samples/bundle-v1-sample.tar.gz (sha256 TBD at publish time).
  • Sample attestation envelope: docs/modules/evidence-locker/samples/attestation-v1-sample.json.

Ownership

  • Primary: Evidence Locker Guild.
  • Reviewers: Concelier Core Guild, Excititor Guild, Export Center Guild, Policy Guild.

Gate Artifact Evidence Score Contract (v1, 2026-02-09)

Evidence Locker accepts a producer bundle and emits a single deterministic gate value (evidence_score) used by Release Orchestrator promotion gates.

Producer submission

POST /evidence

Request body:

  • producer_bundle.artifact_id (required)
  • producer_bundle.canonical_bom_sha256 (required, 64 hex)
  • producer_bundle.dsse_envelope_path (required)
  • producer_bundle.payload_digest (required, 64 hex)
  • producer_bundle.rekor.index (required, integer >= 0)
  • producer_bundle.rekor.tile_id (required)
  • producer_bundle.rekor.inclusion_proof_path (required)
  • producer_bundle.attestation_refs[] (optional list of stable refs)
  • raw_bom_path (optional)
  • vex_refs[] (optional list of refs)

Response body:

  • evidence_id
  • evidence_score
  • stored

Score lookup

GET /evidence/score?artifact_id=<artifact-id>

Response body:

  • evidence_score
  • status (ready)

Deterministic scoring algorithm

Inputs:

  • canonical_bom_sha256
  • payload_digest
  • sorted(attestation_refs) using ordinal lexical sort

Computation:

  • join inputs with ASCII Unit Separator (0x1F)
  • evidence_score = SHA256(joined_bytes) (lowercase hex)

Validation is fail-closed:

  • reject non-hex or non-64-byte digests
  • reject missing required producer fields
  • reject invalid Rekor index values

This contract is authoritative for Sprint 110 and blocks CONCELIER-ATTEST-73-001/002 and EXCITITOR-ATTEST-01-003/73-001/73-002.