# Evidence Pack Schema > **Status:** Implementation in Progress (SPRINT_3000_0100_0002) > **Type URI:** `https://stellaops.dev/evidence-pack@v1` > **Schema:** [`docs/schemas/stellaops-evidence-pack.v1.schema.json`](../schemas/stellaops-evidence-pack.v1.schema.json) --- ## Overview **Evidence Packs** are time-stamped, queryable bundles containing complete policy evaluation context (SBOM, advisories, VEX, policy, verdicts, reachability). They enable: - **Deterministic Replay:** Re-evaluate policy with identical inputs - **Audit & Compliance:** Portable evidence for incident review - **Offline Transfer:** Move evidence between air-gapped environments - **Forensics:** Query pack contents without external dependencies --- ## Pack Structure Evidence packs are **compressed tarballs** (`.tar.gz`) with a signed manifest: ``` evidence-pack-{packId}.tar.gz ├── manifest.json # Signed manifest with content index ├── policy/ │ ├── policy-P-7-v4.json # Policy definition snapshot │ └── policy-run-{runId}.json # Policy run request/status ├── sbom/ │ ├── sbom-S-42.spdx.json # SBOM artifacts │ └── sbom-S-318.spdx.json ├── advisories/ │ ├── nvd-2025-12345.json # Advisory snapshots (timestamped) │ ├── ghsa-2025-0001.json │ └── cve-2025-99999.json ├── vex/ │ ├── vendor-vex-statement-1.json # VEX statements (OpenVEX) │ └── internal-vex-override-2.json ├── verdicts/ │ ├── verdict-finding-1.json # Individual verdict attestations (DSSE) │ ├── verdict-finding-2.json │ └── ... ├── reachability/ │ ├── drift-{scanId}.json # Reachability drift results │ └── slices/ │ └── slice-{digest}.json # Reachability slices └── metadata/ ├── tenant-context.json # Tenant metadata ├── environment.json # Environment context from policy run └── signatures.json # Detached signatures for pack contents ``` --- ## Manifest Format See [`stellaops-evidence-pack.v1.schema.json`](../schemas/stellaops-evidence-pack.v1.schema.json) for complete schema. ### Example Manifest ```json { "_type": "https://stellaops.dev/evidence-pack@v1", "packId": "pack:run:P-7:20251223T140500Z:1b2c3d4e", "generatedAt": "2025-12-23T14:10:00+00:00", "tenantId": "tenant-alpha", "policyRunId": "run:P-7:20251223T140500Z:1b2c3d4e", "policyId": "P-7", "policyVersion": 4, "manifestVersion": "1.0.0", "contents": { "policy": [ { "path": "policy/policy-P-7-v4.json", "digest": "sha256:abc123...", "size": 12345, "mediaType": "application/vnd.stellaops.policy+json" } ], "sbom": [ { "path": "sbom/sbom-S-42.spdx.json", "digest": "sha256:sbom42...", "size": 234567, "mediaType": "application/spdx+json", "sbomId": "sbom:S-42" } ], "advisories": [ { "path": "advisories/nvd-2025-12345.json", "digest": "sha256:adv123...", "size": 4567, "mediaType": "application/vnd.stellaops.advisory+json", "cveId": "CVE-2025-12345", "capturedAt": "2025-12-23T13:59:00+00:00" } ], "vex": [...], "verdicts": [...], "reachability": [...] }, "statistics": { "totalFiles": 47, "totalSize": 5678901, "componentCount": 1742, "findingCount": 234, "verdictCount": 234, "advisoryCount": 89, "vexStatementCount": 12 }, "determinismHash": "sha256:pack-determinism...", "signatures": [ { "keyId": "sha256:keypair123...", "algorithm": "ed25519", "signature": "base64-encoded-signature", "signedAt": "2025-12-23T14:10:05+00:00" } ] } ``` --- ## API Reference ### Create Evidence Pack ```http POST /api/v1/runs/{runId}/evidence-pack ``` **Request:** ```json { "includeReachability": true, "compression": "gzip" } ``` **Response:** ```json { "packId": "pack:run:P-7:20251223T140500Z:1b2c3d4e", "generatedAt": "2025-12-23T14:10:00+00:00", "downloadUri": "/api/v1/evidence-packs/pack:run:P-7:20251223T140500Z:1b2c3d4e", "manifestUri": "/api/v1/evidence-packs/pack:run:P-7:20251223T140500Z:1b2c3d4e/manifest", "packSize": 5678901, "statistics": {...} } ``` ### Download Evidence Pack ```http GET /api/v1/evidence-packs/{packId} Accept: application/gzip ``` **Response:** Binary tarball (`.tar.gz`) ### Inspect Manifest ```http GET /api/v1/evidence-packs/{packId}/manifest ``` **Response:** JSON manifest (without downloading full pack) ### Replay Policy from Pack ```http POST /api/v1/evidence-packs/{packId}/replay ``` **Response:** ```json { "replayId": "replay:pack:...:20251223T150000Z", "packId": "pack:run:P-7:20251223T140500Z:1b2c3d4e", "originalRunId": "run:P-7:20251223T140500Z:1b2c3d4e", "determinismVerified": true, "verdictComparison": { "totalOriginal": 234, "totalReplay": 234, "identical": 234, "differences": [] }, "replayDuration": 45.2 } ``` ### Verify Pack Integrity ```http POST /api/v1/evidence-packs/{packId}/verify ``` **Response:** ```json { "packId": "pack:run:P-7:20251223T140500Z:1b2c3d4e", "manifestSignatureValid": true, "contentIntegrityValid": true, "verifiedAt": "2025-12-23T15:00:00+00:00", "verifications": [ { "file": "policy/policy-P-7-v4.json", "expectedDigest": "sha256:abc123...", "actualDigest": "sha256:abc123...", "valid": true }, // ... all files ] } ``` --- ## CLI Usage ### Create Pack ```bash stella pack create run:P-7:20251223T140500Z:1b2c3d4e # Output: # Assembling evidence pack... # ✓ Policy definition (12 KB) # ✓ SBOMs (2 files, 450 KB) # ✓ Advisories (89 files, 234 KB) # ✓ VEX statements (12 files, 45 KB) # ✓ Verdicts (234 files, 567 KB) # ✓ Reachability data (18 KB) # # Pack created: pack:run:P-7:20251223T140500Z:1b2c3d4e # Size: 5.4 MB (compressed) # Download: stella pack download pack:run:P-7:20251223T140500Z:1b2c3d4e ``` ### Download Pack ```bash stella pack download pack:run:P-7:20251223T140500Z:1b2c3d4e --output ./evidence-pack.tar.gz # Output: # Downloading pack:run:P-7:20251223T140500Z:1b2c3d4e... # Downloaded 5.4 MB to ./evidence-pack.tar.gz ``` ### Inspect Pack ```bash stella pack inspect evidence-pack.tar.gz # Output: # Pack ID: pack:run:P-7:20251223T140500Z:1b2c3d4e # Generated: 2025-12-23T14:10:00+00:00 # Policy: P-7 (version 4) # Tenant: tenant-alpha # # Contents: # Policy: 2 files (12 KB) # SBOMs: 2 files (450 KB) - 1,742 components # Advisories: 89 files (234 KB) # VEX: 12 files (45 KB) # Verdicts: 234 files (567 KB) # Reachability: 3 files (18 KB) # # Total: 342 files, 1.3 MB (5.4 MB compressed) # Determinism hash: sha256:pack-determinism... # Signature: ✓ Verified (ed25519) ``` ### List Pack Contents ```bash stella pack list evidence-pack.tar.gz # Output: # manifest.json (signed manifest) # policy/policy-P-7-v4.json # policy/policy-run-run:P-7:20251223T140500Z:1b2c3d4e.json # sbom/sbom-S-42.spdx.json # sbom/sbom-S-318.spdx.json # advisories/nvd-2025-12345.json # ... ``` ### Extract Artifact ```bash stella pack export evidence-pack.tar.gz \ --artifact sbom/sbom-S-42.spdx.json \ --output ./sbom-S-42.spdx.json # Output: # Extracted sbom/sbom-S-42.spdx.json → ./sbom-S-42.spdx.json ``` ### Verify Pack ```bash stella pack verify evidence-pack.tar.gz # Output: # Verifying pack:run:P-7:20251223T140500Z:1b2c3d4e... # ✓ Manifest signature valid # ✓ Content integrity (342/342 files) # ✓ Determinism hash matches # # Pack is valid and tamper-free ``` ### Replay Policy ```bash stella pack replay evidence-pack.tar.gz # Output: # Replaying policy P-7 (version 4)... # Loading SBOMs (2 files)... # Loading advisories (89 files)... # Loading VEX statements (12 files)... # Evaluating 1,742 components... # # Replay completed in 45.2s # ✓ Determinism verified # ✓ 234/234 verdicts match original # # Original run: run:P-7:20251223T140500Z:1b2c3d4e # Replay run: replay:pack:...:20251223T150000Z ``` --- ## Deterministic Replay Evidence packs enable **deterministic policy replay**: ### Prerequisites 1. **Complete Context:** Pack contains all inputs (SBOMs, advisories, VEX, policy, environment) 2. **Timestamp Anchoring:** Advisory/VEX snapshots captured at exact cursor timestamps 3. **Canonical Inputs:** All inputs normalized and sorted deterministically ### Replay Process ``` 1. Extract Pack → Verify Signature 2. Load Policy Definition (P-7 v4) 3. Load SBOMs (S-42, S-318) 4. Load Advisory Snapshots (at cursor 2025-12-23T13:59:00Z) 5. Load VEX Snapshots (at cursor 2025-12-23T13:58:30Z) 6. Reconstruct Policy Inputs (identical to original run) 7. Execute Policy Evaluation 8. Compare Replay Verdicts to Original Verdicts 9. Report Determinism Status ``` ### Determinism Validation ```bash # Replay and compare stella pack replay evidence-pack.tar.gz --compare # Output includes: # - Total verdicts: 234 # - Matching: 234 # - Differences: 0 # - Determinism hash: sha256:... (matches original) ``` --- ## Air-Gap Transfer Evidence packs support **offline/air-gapped** workflows: ### Export from Online Environment ```bash # Create pack from policy run stella pack create run:P-7:20251223T140500Z:1b2c3d4e --output ./pack.tar.gz # Verify before transfer stella pack verify ./pack.tar.gz ``` ### Transfer ```bash # Copy to removable media or secure transfer channel cp ./pack.tar.gz /media/usb-drive/ ``` ### Import to Air-Gapped Environment ```bash # Verify pack integrity stella pack verify /media/usb-drive/pack.tar.gz # Replay policy (offline, no network) stella pack replay /media/usb-drive/pack.tar.gz # Extract artifacts stella pack export /media/usb-drive/pack.tar.gz \ --artifact verdicts/verdict-finding-1.json \ --output ./verdict-1.json ``` --- ## Performance ### Pack Assembly Time | Component Count | Findings | Pack Size | Assembly Time | |----------------|----------|-----------|---------------| | 100 | 10 | 500 KB | 2s | | 1,000 | 100 | 5 MB | 15s | | 10,000 | 1,000 | 50 MB | 2min | | 100,000 | 10,000 | 500 MB | 20min | ### Replay Time Replay time ≈ 90% of original policy run time (overhead from deserialization) --- ## Storage ### Retention Policy | Age | Storage Tier | Access Pattern | |-----|--------------|----------------| | < 7 days | Hot (PostgreSQL + S3 Standard) | Frequent | | 7-30 days | Warm (S3 Infrequent Access) | Occasional | | 30-90 days | Cold (S3 Glacier) | Rare | | > 90 days | Archive (S3 Deep Archive) | Compliance-only | ### Compression Ratios | Content Type | Uncompressed | Compressed | Ratio | |--------------|--------------|------------|-------| | SBOMs (JSON) | 10 MB | 2 MB | 5:1 | | Advisories (JSON) | 5 MB | 1 MB | 5:1 | | Verdicts (DSSE) | 15 MB | 4 MB | 3.75:1 | | **Total Pack** | 30 MB | 7 MB | 4.3:1 | --- ## Security ### Manifest Signing - **Algorithm:** Ed25519 (default), ECDSA P-256, RSA-PSS - **Key Storage:** KMS, CryptoPro (GOST), offline signing ceremony - **Verification:** Public key bundled or fetched from trusted registry ### Content Integrity - **Per-File Digests:** SHA-256/SHA-384/SHA-512 for each artifact - **Determinism Hash:** Aggregate hash over sorted content digests - **Tamper Detection:** Any file modification invalidates manifest signature ### Access Control - **Pack Creation:** `policy:pack:create` scope - **Pack Download:** `policy:pack:read` scope - **Pack Replay:** `policy:replay` scope - **Tenant Isolation:** Packs scoped by `tenantId` --- ## Troubleshooting ### Pack Assembly Failed **Symptom:** `POST /api/v1/runs/{runId}/evidence-pack` returns 500 **Causes:** 1. Missing artifacts (SBOM/VEX not found) 2. Object store unavailable 3. Signing key unavailable **Resolution:** ```bash # Check policy run completed stella policy status run:P-7:20251223T140500Z:1b2c3d4e # Verify all artifacts present stella pack validate-inputs run:P-7:20251223T140500Z:1b2c3d4e # Retry pack creation stella pack create run:P-7:20251223T140500Z:1b2c3d4e ``` ### Determinism Failure on Replay **Symptom:** Replay verdicts differ from original **Causes:** 1. Advisory/VEX drift (cursor mismatch) 2. Policy definition changed 3. Non-deterministic evaluation logic **Resolution:** ```bash # Compare inputs stella pack diff-inputs evidence-pack.tar.gz --original-run run:... # Identify divergence stella pack replay evidence-pack.tar.gz --verbose --diff # Output shows: # - Finding X: original=blocked, replay=warned # - Cause: VEX statement vex:... not found in pack ``` --- ## References - [Policy Replay Workflow](../policy/replay-workflow.md) - [Verdict Attestations](../policy/verdict-attestations.md) - [Evidence Locker Architecture](../modules/evidence-locker/architecture.md) - [SPRINT_3000_0100_0002](../implplan/SPRINT_3000_0100_0002_evidence_packs.md)