# Evidence Bundle Format Specification Version: 1.0 Status: Stable Sprint: SPRINT_9200_0001_0003 ## Overview Evidence bundles are downloadable archives containing complete evidence packages for findings or scan runs. They enable: - **Offline verification**: All evidence is self-contained - **Deterministic replay**: Includes scripts and hashes for verdict reproduction - **Audit compliance**: Provides cryptographic verification of all evidence - **Human readability**: Includes README and manifest for easy inspection ## Archive Formats Evidence bundles are available in two formats: | Format | Extension | MIME Type | Use Case | |--------|-----------|-----------|----------| | ZIP | `.zip` | `application/zip` | General use, Windows compatible | | TAR.GZ | `.tar.gz` | `application/gzip` | Unix systems, better compression | ## Endpoints ### Single Finding Bundle ``` GET /v1/triage/findings/{findingId}/evidence/export?format=zip ``` Response headers: - `Content-Type: application/zip` - `Content-Disposition: attachment; filename="evidence-{findingId}.zip"` - `X-Archive-Digest: sha256:{digest}` ### Scan Run Bundle ``` GET /v1/triage/scans/{scanId}/evidence/export?format=zip ``` Response headers: - `Content-Type: application/zip` - `Content-Disposition: attachment; filename="evidence-run-{scanId}.zip"` - `X-Archive-Digest: sha256:{digest}` ## Finding Bundle Structure ``` evidence-{findingId}/ ├── manifest.json # Archive manifest with file hashes ├── README.md # Human-readable documentation ├── sbom.cdx.json # CycloneDX SBOM slice ├── reachability.json # Reachability analysis data ├── vex/ │ ├── vendor.json # Vendor VEX statements │ ├── nvd.json # NVD VEX data │ └── cisa-kev.json # CISA KEV data ├── attestations/ │ ├── sbom.dsse.json # SBOM DSSE envelope │ └── scan.dsse.json # Scan DSSE envelope ├── policy/ │ └── evaluation.json # Policy evaluation result ├── delta.json # Delta comparison (if available) ├── replay-command.txt # Copy-ready replay command ├── replay.sh # Bash replay script └── replay.ps1 # PowerShell replay script ``` ## Scan Run Bundle Structure ``` evidence-run-{scanId}/ ├── MANIFEST.json # Run-level manifest ├── README.md # Run-level documentation └── findings/ ├── {findingId1}/ │ ├── manifest.json │ ├── README.md │ ├── sbom.cdx.json │ ├── reachability.json │ ├── vex/ │ ├── attestations/ │ ├── policy/ │ ├── delta.json │ ├── replay-command.txt │ ├── replay.sh │ └── replay.ps1 ├── {findingId2}/ │ └── ... └── ... ``` ## Manifest Schema ### Finding Manifest (manifest.json) ```json { "schemaVersion": "1.0", "findingId": "f-abc123", "generatedAt": "2025-01-15T10:30:00Z", "cacheKey": "sha256:abc123...", "scannerVersion": "10.1.3", "files": [ { "path": "sbom.cdx.json", "sha256": "abc123def456...", "size": 12345, "contentType": "application/json" }, { "path": "reachability.json", "sha256": "789xyz...", "size": 5678, "contentType": "application/json" } ] } ``` ### Run Manifest (MANIFEST.json) ```json { "schemaVersion": "1.0", "scanId": "scan-xyz789", "generatedAt": "2025-01-15T10:30:00Z", "totalFiles": 42, "scannerVersion": "10.1.3", "findings": [ { "findingId": "f-abc123", "generatedAt": "2025-01-15T10:30:00Z", "cacheKey": "sha256:abc123...", "files": [...] }, { "findingId": "f-def456", "generatedAt": "2025-01-15T10:30:00Z", "cacheKey": "sha256:def456...", "files": [...] } ] } ``` ## Replay Scripts ### Bash Script (replay.sh) ```bash #!/usr/bin/env bash # StellaOps Evidence Bundle Replay Script # Generated: 2025-01-15T10:30:00Z # Finding: f-abc123 # CVE: CVE-2024-1234 set -euo pipefail # Input hashes for deterministic replay ARTIFACT_DIGEST="sha256:a1b2c3d4e5f6..." MANIFEST_HASH="sha256:abc123def456..." FEED_HASH="sha256:feed789feed..." POLICY_HASH="sha256:policy321..." # Verify prerequisites if ! command -v stella &> /dev/null; then echo "Error: stella CLI not found. Install from https://stellaops.org/install" exit 1 fi echo "Replaying verdict for finding: ${ARTIFACT_DIGEST}" echo "Using manifest: ${MANIFEST_HASH}" # Execute replay stella scan replay \ --artifact "${ARTIFACT_DIGEST}" \ --manifest "${MANIFEST_HASH}" \ --feeds "${FEED_HASH}" \ --policy "${POLICY_HASH}" echo "Replay complete. Verify verdict matches original." ``` ### PowerShell Script (replay.ps1) ```powershell # StellaOps Evidence Bundle Replay Script # Generated: 2025-01-15T10:30:00Z # Finding: f-abc123 # CVE: CVE-2024-1234 $ErrorActionPreference = 'Stop' # Input hashes for deterministic replay $ArtifactDigest = "sha256:a1b2c3d4e5f6..." $ManifestHash = "sha256:abc123def456..." $FeedHash = "sha256:feed789feed..." $PolicyHash = "sha256:policy321..." # Verify prerequisites if (-not (Get-Command stella -ErrorAction SilentlyContinue)) { Write-Error "stella CLI not found. Install from https://stellaops.org/install" exit 1 } Write-Host "Replaying verdict for finding: $ArtifactDigest" Write-Host "Using manifest: $ManifestHash" # Execute replay stella scan replay ` --artifact $ArtifactDigest ` --manifest $ManifestHash ` --feeds $FeedHash ` --policy $PolicyHash Write-Host "Replay complete. Verify verdict matches original." ``` ## README Format ### Finding README (README.md) ```markdown # StellaOps Evidence Bundle ## Overview - **Finding ID:** `f-abc123` - **CVE:** `CVE-2024-1234` - **Component:** `pkg:npm/lodash@4.17.15` - **Generated:** 2025-01-15T10:30:00Z ## Input Hashes for Deterministic Replay | Input | Hash | |-------|------| | Artifact Digest | `sha256:a1b2c3d4e5f6...` | | Run Manifest | `sha256:abc123def456...` | | Feed Snapshot | `sha256:feed789feed...` | | Policy | `sha256:policy321...` | ## Replay Instructions ### Using Bash ```bash chmod +x replay.sh ./replay.sh ``` ### Using PowerShell ```powershell .\replay.ps1 ``` ## Bundle Contents | File | SHA-256 | Size | |------|---------|------| | `sbom.cdx.json` | `abc123...` | 12.3 KB | | `reachability.json` | `789xyz...` | 5.6 KB | | ... | ... | ... | ## Verification Status - **Status:** verified - **Hashes Verified:** ✓ - **Attestations Verified:** ✓ - **Evidence Complete:** ✓ --- *Generated by StellaOps Scanner* ``` ## Integrity Verification To verify bundle integrity: 1. **Download with digest header**: The `X-Archive-Digest` response header contains the archive's SHA-256 hash 2. **Verify archive hash**: `sha256sum evidence-{findingId}.zip` 3. **Verify file hashes**: Compare each file's SHA-256 against `manifest.json` Example verification: ```bash # Verify archive integrity EXPECTED_HASH="abc123..." ACTUAL_HASH=$(sha256sum evidence-f-abc123.zip | cut -d' ' -f1) if [ "$EXPECTED_HASH" = "$ACTUAL_HASH" ]; then echo "Archive integrity verified" else echo "Archive integrity check FAILED" exit 1 fi # Verify individual files cd evidence-f-abc123 for file in $(jq -r '.files[].path' manifest.json); do expected=$(jq -r ".files[] | select(.path==\"$file\") | .sha256" manifest.json) actual=$(sha256sum "$file" | cut -d' ' -f1) if [ "$expected" = "$actual" ]; then echo "✓ $file" else echo "✗ $file" fi done ``` ## Content Types | File Type | Content-Type | Description | |-----------|--------------|-------------| | `.json` | `application/json` | JSON data files | | `.cdx.json` | `application/json` | CycloneDX SBOM | | `.dsse.json` | `application/json` | DSSE envelope | | `.sh` | `text/x-shellscript` | Bash script | | `.ps1` | `text/plain` | PowerShell script | | `.md` | `text/markdown` | Markdown documentation | | `.txt` | `text/plain` | Plain text | ## See Also - [stella scan replay Command Reference](../cli/guides/commands/scan-replay.md) - [Deterministic Replay Specification](../replay/DETERMINISTIC_REPLAY.md) - [Unified Evidence Endpoint API](./unified-evidence-endpoint.md)