8.3 KiB
8.3 KiB
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/zipContent-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/zipContent-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)
{
"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)
{
"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)
#!/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)
# 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)
# 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
.\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 |