18 KiB
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:
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:
{
"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
{
"sboms": [
{
"scan_id": "scan-abc123",
"format": "cyclonedx-1.6",
"path": "sboms/scan-abc123.cdx.json",
"sha256": "abc123...",
"size": 89012
}
]
}
Scan Result Collection
{
"scan_results": [
{
"scan_id": "scan-abc123",
"path": "scans/scan-abc123.json",
"sha256": "def456...",
"finding_count": 12,
"verdict": "PASS"
}
]
}
Policy Verdict Collection
{
"policy_verdicts": [
{
"scan_id": "scan-abc123",
"policy_set": "production",
"path": "verdicts/scan-abc123-production.json",
"sha256": "ghi789...",
"verdict": "PASS",
"confidence": 0.92
}
]
}
Attestation Collection
{
"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:
{
"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
{
"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:
{
"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:
# 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
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
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
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
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 - General export mechanics
- Scan Submission Flow - Source of evidence
- Offline Sync Flow - Air-gapped bundle transfer