3.5 KiB
3.5 KiB
Export Attestation Prep — PREP-EXPORT-ATTEST-74-001
Status: Ready for implementation (2025-11-20) Owners: Attestation Bundle Guild · Exporter Service Guild Scope: Produce deterministic attestation export bundles for air-gap/offline delivery, leveraging EvidenceLocker DSSE layout and orchestrator events.
Dependencies
- EvidenceLocker packaging & DSSE conventions:
docs/modules/evidence-locker/bundle-packaging.md. - Attestor air-gap guidance:
docs/modules/attestor/airgap.md(statement + predicate expectations). - Orchestrator event envelopes (Wave 150/140) for optional timeline/notification mirrors; not required to start packaging.
Export bundle contract (v1)
- Input: attestation record id (
attestationId) referencing a sealed DSSE statement (e.g., in-toto) stored by EvidenceLocker/Attestor. - Packaging: create deterministic gzip/tar
export-attestation-bundle-v1.tgzwith fixed mtime2025-01-01T00:00:00Z, PAX headers,0644perms, owner/group0.
export-attestation-bundle-v1.tgz
├── attestation.dsse.json # Original DSSE envelope (statement + signature), unchanged
├── statement.json # Extracted statement/predicate for quick inspection
├── transparency.ndjson # Optional Rekor/CT entries (one per line, canonical JSON)
├── metadata.json # exportId, attestationId, subject digests, rootHash, createdAtUtc, sourceUri
├── checksums.txt # SHA256 hashes (lexical order); first line `root <sha256(export-attestation-bundle-v1.tgz)>`
└── verify-attestation.sh # POSIX script: checksum, DSSE verify (invokes `stella attest verify` if available)
- No re-signing; DSSE envelope is copied bit-for-bit from source.
transparency.ndjsonomitted when no log entries exist; maintain deterministic ordering otherwise.
API surface (ExportCenter)
POST /v1/exports/attestations/{attestationId}→202 AcceptedwithexportId,status=pending.GET /v1/exports/attestations/{exportId}→ status + metadata (rootHash,downloadUri,attestationDigests).GET /v1/exports/attestations/{exportId}/download→application/gzip, filenameexport-attestation-bundle-v1.tgz,ETag=SHA256.- Auth:
export:writefor POST,export:readfor GET/Download; tenant scoped.
Determinism & observability
- All timestamps captured once at export creation (UTC ISO-8601) and reused; archive mtimes/gzip mtime pinned.
- Structured log on completion
{exportId, attestationId, subjectDigests, rootHash}; counterexport.attest.completedand histogramexport.attest.duration_ms. - Retries for fetch/pack errors use exponential backoff identical to 57-001 portable export.
Acceptance criteria
- Export archive is byte-identical across replays for the same (
attestationId,exportId). - DSSE envelope and statement are unchanged relative to source; hashes in
checksums.txtmatch download and DSSE payload. - API responses document 202/404/409/500 paths;
downloadUrireturns sealed artifact with deterministic ETag. - Verification script runs offline using only
tar+sha256sum/shasum; optionally callsstella attest verifywhen present.
Open items / risks
- Notification/timeline emission pending envelope schema; add once Wave 150/140 lands.
- If attestation format changes (predicate versions), bump
statementVersioninmetadata.jsonand announce.
Handoff
- Implement in
StellaOps.ExportCenter.Workerexport job + WebService endpoints above. - Link this document from Sprint 0162 entry P6 and close PREP when endpoints + packaging align.