# Evidence Bundle Export Flow ## Overview The Evidence Bundle Export Flow describes how StellaOps creates comprehensive, cryptographically sealed evidence packages for audits, compliance, and legal proceedings. Bundles include SBOMs, scan results, policy verdicts, attestations, and complete provenance chains with tamper-evident sealing. **Business Value**: Auditable, legally defensible evidence packages that demonstrate due diligence in vulnerability management and support regulatory compliance. ## Actors | Actor | Type | Role | |-------|------|------| | Auditor | Human | Requests and verifies evidence bundles | | Compliance Officer | Human | Configures bundle requirements | | EvidenceLocker | Service | Creates and seals bundles | | Scanner | Service | Provides scan artifacts | | Policy | Service | Provides verdict artifacts | | Attestor | Service | Provides attestations | | Signer | Service | Signs bundle manifest | ## Prerequisites - Evidence exists for requested scope - Bundle schema configured - Signing keys available - Storage quota available ## Bundle Contents | Artifact Type | Format | Description | |---------------|--------|-------------| | SBOM | CycloneDX/SPDX | Software bill of materials | | Scan Result | JSON | Vulnerability findings | | Policy Verdict | JSON | Policy evaluation result | | Attestation | DSSE | in-toto attestation envelope | | VEX Statements | OpenVEX | Applied VEX statements | | Reachability | JSON | K4 lattice state evidence | | Audit Log | NDJSON | Activity audit trail | | Manifest | JSON | Bundle index with hashes | ## Flow Diagram ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Evidence Bundle Export Flow │ └─────────────────────────────────────────────────────────────────────────────────┘ ┌─────────┐ ┌───────────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ ┌────────┐ │ Auditor │ │EvidenceLocker │ │ Scanner │ │ Policy │ │Attestor│ │ Signer │ └────┬────┘ └───────┬───────┘ └────┬────┘ └────┬────┘ └───┬────┘ └───┬────┘ │ │ │ │ │ │ │ Request │ │ │ │ │ │ bundle │ │ │ │ │ │──────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ Validate │ │ │ │ │ │ request │ │ │ │ │ │───┐ │ │ │ │ │ │ │ │ │ │ │ │ │<──┘ │ │ │ │ │ │ │ │ │ │ │ │ Collect scan │ │ │ │ │ │ artifacts │ │ │ │ │ │──────────────>│ │ │ │ │ │ │ │ │ │ │ │ SBOM + result │ │ │ │ │ │<──────────────│ │ │ │ │ │ │ │ │ │ │ │ Collect │ │ │ │ │ │ verdicts │ │ │ │ │ │───────────────────────────>│ │ │ │ │ │ │ │ │ │ │ Policy eval │ │ │ │ │ │<───────────────────────────│ │ │ │ │ │ │ │ │ │ │ Collect │ │ │ │ │ │ attestations │ │ │ │ │ │───────────────────────────────────────>│ │ │ │ │ │ │ │ │ │ DSSE │ │ │ │ │ │ envelopes │ │ │ │ │ │<───────────────────────────────────────│ │ │ │ │ │ │ │ │ │ Build │ │ │ │ │ │ manifest │ │ │ │ │ │───┐ │ │ │ │ │ │ │ │ │ │ │ │ │<──┘ │ │ │ │ │ │ │ │ │ │ │ │ Compute │ │ │ │ │ │ Merkle root │ │ │ │ │ │───┐ │ │ │ │ │ │ │ │ │ │ │ │ │<──┘ │ │ │ │ │ │ │ │ │ │ │ │ Sign bundle │ │ │ │ │ │───────────────────────────────────────────────────>│ │ │ │ │ │ │ │ │ Signature │ │ │ │ │ │<───────────────────────────────────────────────────│ │ │ │ │ │ │ │ │ Seal bundle │ │ │ │ │ │───┐ │ │ │ │ │ │ │ │ │ │ │ │ │<──┘ │ │ │ │ │ │ │ │ │ │ │ Bundle + │ │ │ │ │ │ download URL │ │ │ │ │ │<──────────────│ │ │ │ │ │ │ │ │ │ │ ``` ## Step-by-Step ### 1. Bundle Request Auditor requests evidence bundle: ```http POST /api/v1/evidence/bundles HTTP/1.1 Authorization: Bearer {jwt} X-Tenant-Id: acme-corp Content-Type: application/json { "name": "Q4-2024-Compliance-Audit", "description": "Evidence bundle for SOC2 Type II audit", "scope": { "scan_ids": ["scan-abc123", "scan-def456"], "date_range": { "start": "2024-10-01T00:00:00Z", "end": "2024-12-31T23:59:59Z" }, "images": ["docker.io/myorg/*"], "policy_sets": ["production", "pci-dss"] }, "include": { "sbom": true, "scan_results": true, "policy_verdicts": true, "attestations": true, "vex_statements": true, "reachability": true, "audit_log": true, "provenance_chain": true }, "format": { "archive": "tar.gz", "signing": "sigstore", "transparency_log": true } } ``` ### 2. Scope Validation EvidenceLocker validates the request scope: ```json { "validation": { "scope_valid": true, "artifacts_found": { "scans": 47, "images": 23, "sboms": 47, "attestations": 47, "vex_statements": 156 }, "estimated_size": "245 MB", "estimated_generation_time": "PT3M" } } ``` ### 3. Artifact Collection EvidenceLocker collects artifacts from each service: #### SBOM Collection ```json { "sboms": [ { "scan_id": "scan-abc123", "format": "cyclonedx-1.6", "path": "sboms/scan-abc123.cdx.json", "sha256": "abc123...", "size": 89012 } ] } ``` #### Scan Result Collection ```json { "scan_results": [ { "scan_id": "scan-abc123", "path": "scans/scan-abc123.json", "sha256": "def456...", "finding_count": 12, "verdict": "PASS" } ] } ``` #### Policy Verdict Collection ```json { "policy_verdicts": [ { "scan_id": "scan-abc123", "policy_set": "production", "path": "verdicts/scan-abc123-production.json", "sha256": "ghi789...", "verdict": "PASS", "confidence": 0.92 } ] } ``` #### Attestation Collection ```json { "attestations": [ { "scan_id": "scan-abc123", "type": "sbom", "path": "attestations/scan-abc123-sbom.dsse.json", "sha256": "jkl012...", "signer": "scanner@stellaops.local" }, { "scan_id": "scan-abc123", "type": "verdict", "path": "attestations/scan-abc123-verdict.dsse.json", "sha256": "mno345...", "signer": "policy@stellaops.local" } ] } ``` ### 4. Manifest Generation EvidenceLocker creates bundle manifest: ```json { "manifest_version": "1.0.0", "bundle_id": "bundle-789ghi", "created_at": "2024-12-29T10:30:00Z", "created_by": "auditor@acme.com", "tenant_id": "acme-corp", "scope": { "scan_count": 47, "image_count": 23, "date_range": { "start": "2024-10-01T00:00:00Z", "end": "2024-12-31T23:59:59Z" } }, "contents": { "sboms": { "count": 47, "path": "sboms/", "index": "sboms/index.json" }, "scans": { "count": 47, "path": "scans/", "index": "scans/index.json" }, "verdicts": { "count": 94, "path": "verdicts/", "index": "verdicts/index.json" }, "attestations": { "count": 188, "path": "attestations/", "index": "attestations/index.json" }, "vex": { "count": 156, "path": "vex/", "index": "vex/index.json" }, "audit_log": { "path": "audit/activity.ndjson", "entries": 1247 } }, "integrity": { "algorithm": "sha256", "merkle_root": "sha256:merkle-root-hash...", "file_hashes": "hashes.json" } } ``` ### 5. Merkle Tree Construction EvidenceLocker computes Merkle root for tamper detection: ``` merkle_root / \ hash_01 hash_23 / \ / \ hash_0 hash_1 hash_2 hash_3 | | | | sbom_0 sbom_1 scan_0 scan_1 ``` ```json { "merkle_tree": { "algorithm": "sha256", "root": "sha256:abc123...", "leaves": [ {"path": "sboms/scan-abc123.cdx.json", "hash": "sha256:..."}, {"path": "scans/scan-abc123.json", "hash": "sha256:..."}, {"path": "verdicts/scan-abc123-production.json", "hash": "sha256:..."} ], "proof_format": "rfc6962" } } ``` ### 6. Bundle Signing Signer creates signature over manifest: ```json { "signed_manifest": { "payload": "base64:manifest-json...", "signatures": [ { "keyid": "sha256:evidence-signing-key", "sig": "base64:signature...", "certificate": "base64:x509-cert...", "timestamp": "2024-12-29T10:30:00Z" } ] }, "transparency_log": { "enabled": true, "rekor_log_index": 12345678, "inclusion_proof": "base64:proof..." } } ``` ### 7. Bundle Sealing EvidenceLocker creates final sealed archive: ``` bundle-789ghi.tar.gz ├── manifest.json # Bundle manifest ├── manifest.sig # Manifest signature ├── hashes.json # All file hashes ├── merkle.json # Merkle tree structure ├── sboms/ │ ├── index.json │ ├── scan-abc123.cdx.json │ └── scan-def456.cdx.json ├── scans/ │ ├── index.json │ ├── scan-abc123.json │ └── scan-def456.json ├── verdicts/ │ ├── index.json │ ├── scan-abc123-production.json │ └── scan-abc123-pci-dss.json ├── attestations/ │ ├── index.json │ ├── scan-abc123-sbom.dsse.json │ └── scan-abc123-verdict.dsse.json ├── vex/ │ ├── index.json │ └── vex-statements.json ├── audit/ │ └── activity.ndjson └── README.md # Bundle documentation ``` ### 8. Verification Auditor can verify bundle integrity: ```bash # Verify bundle signature stellaops evidence verify bundle-789ghi.tar.gz # Output: ✓ Manifest signature valid ✓ Merkle root verified ✓ 47 SBOMs verified ✓ 47 scan results verified ✓ 94 verdicts verified ✓ 188 attestations verified ✓ Transparency log inclusion verified (Rekor #12345678) Bundle verified successfully. ``` ## Bundle Schemas ### Compliance-Focused Bundle ```yaml compliance_bundle: include: - sbom - scan_results - policy_verdicts - attestations - audit_log format: archive: tar.gz encryption: aes-256-gcm signing: sigstore retention: 7y ``` ### Incident Response Bundle ```yaml incident_bundle: scope: images: ["affected-image:*"] date_range: auto # From first detection include: - sbom - scan_results - reachability - runtime_signals - vex_statements format: archive: zip signing: internal priority: urgent ``` ## Data Contracts ### Bundle Request Schema ```typescript interface BundleRequest { name: string; description?: string; scope: { scan_ids?: string[]; date_range?: DateRange; images?: string[]; // Glob patterns policy_sets?: string[]; tenants?: string[]; // Multi-tenant }; include: { sbom?: boolean; scan_results?: boolean; policy_verdicts?: boolean; attestations?: boolean; vex_statements?: boolean; reachability?: boolean; audit_log?: boolean; provenance_chain?: boolean; }; format: { archive: 'tar.gz' | 'zip'; signing: 'sigstore' | 'internal' | 'none'; encryption?: { algorithm: 'aes-256-gcm'; recipient_keys: string[]; }; transparency_log?: boolean; }; } ``` ### Bundle Response Schema ```typescript interface BundleResponse { bundle_id: string; status: 'queued' | 'generating' | 'completed' | 'failed'; created_at: string; completed_at?: string; manifest: BundleManifest; download: { url: string; expires_at: string; size_bytes: number; sha256: string; }; verification: { merkle_root: string; signature: string; rekor_log_index?: number; }; } ``` ## Error Handling | Error | Recovery | |-------|----------| | Scope too large | Suggest date range reduction | | Missing artifacts | Generate partial bundle with warning | | Signing failure | Retry or fall back to internal signing | | Storage quota exceeded | Alert admin, queue for later | ## Observability ### Metrics | Metric | Type | Labels | |--------|------|--------| | `evidence_bundles_created_total` | Counter | `status` | | `evidence_bundle_size_bytes` | Histogram | - | | `evidence_bundle_generation_seconds` | Histogram | - | | `evidence_bundle_artifact_count` | Histogram | `type` | ### Key Log Events | Event | Level | Fields | |-------|-------|--------| | `evidence.bundle.requested` | INFO | `bundle_id`, `scope` | | `evidence.bundle.generating` | INFO | `bundle_id`, `artifact_count` | | `evidence.bundle.sealed` | INFO | `bundle_id`, `size_bytes`, `merkle_root` | | `evidence.bundle.verified` | INFO | `bundle_id`, `verifier` | ## Related Flows - [Export Flow](06-export-flow.md) - General export mechanics - [Scan Submission Flow](02-scan-submission-flow.md) - Source of evidence - [Offline Sync Flow](16-offline-sync-flow.md) - Air-gapped bundle transfer