- Introduced README.md for Zastava Evidence Locker Plan detailing artifacts to sign and post-signing steps. - Added example JSON schemas for observer events and webhook admissions. - Updated implementor guidelines with checklist for CI linting, determinism, secrets management, and schema control. - Created alert rules for Vuln Explorer to monitor API latency and projection errors. - Developed analytics ingestion plan for Vuln Explorer, focusing on telemetry and PII guardrails. - Implemented Grafana dashboard configuration for Vuln Explorer metrics visualization. - Added expected projection SHA256 for vulnerability events. - Created k6 load testing script for Vuln Explorer API. - Added sample projection and replay event data for testing. - Implemented ReplayInputsLock for deterministic replay inputs management. - Developed tests for ReplayInputsLock to ensure stable hash computation. - Created SurfaceManifestDeterminismVerifier to validate manifest determinism and integrity. - Added unit tests for SurfaceManifestDeterminismVerifier to ensure correct functionality. - Implemented Angular tests for VulnerabilityHttpClient and VulnerabilityDetailComponent to verify API interactions and UI rendering.
5.2 KiB
Evidence Locker Bundle Packaging
Sprint 160 / Task EVID-OBS-54-002 — deterministic tarball packaging for download/export.
The Evidence Locker emits a single bundle.tgz artifact for every sealed bundle. The artifact is deterministic so that operators can re-run packaging and obtain identical bytes when the manifest and signature are unchanged.
Layout
The tar stream is written with POSIX/PAX entries and wrapped in a gzip layer:
bundle.tgz
├── manifest.json # Re-emitted DSSE payload (pretty JSON, canonical ordering)
├── signature.json # DSSE signature + key metadata + RFC3161 timestamp (if present)
├── bundle.json # Locker metadata (ids, status, root hash, storage key, timestamps)
├── checksums.txt # SHA-256 root hash + per-entry hashes from the manifest
└── instructions.txt # Offline verification steps and retention guidance
Determinism traits
- Gzip header timestamp is pinned to
2025-01-01T00:00:00Zso CI fixtures remain stable. - All tar entries use the same fixed mtime/atime/ctime,
0644permissions, and UTF-8 encoding. - JSON files are serialized with
JsonSerializerDefaults.Web+ indentation to stabilise ordering. checksums.txtsorts manifest entries bycanonicalPathand prefixes the Merkle root (root <hash>).instructions.txtconditionally adds timestamp verification steps when an RFC3161 token exists.
Download endpoint
GET /evidence/{bundleId}/download
- Requires scopes:
evidence:read. - Streams
application/gzipcontent withContent-Disposition: attachment; filename="bundle.tgz". - Emits quota headers (
X-Stella-Quota-*) and audit events mirroring snapshot fetches. - Returns
404when the bundle is not sealed or the package has not been materialised.
The endpoint reuses EvidenceBundlePackagingService and caches the packaged object in the configured object store (tenants/{tenant}/bundles/{bundle}/bundle.tgz). If the underlying storage key changes (for example, during migration from filesystem to S3), the repository is updated atomically.
Verification guidance
Upcoming EB1–EB10 remediation (Sprint 0161; advisory docs/product-advisories/28-Nov-2025 - Evidence Bundle and Replay Contracts.md):
- Publish
bundle.manifest.schema.jsonandchecksums.schema.jsonwith canonical JSON rules and signatures. - Document the Merkle hash recipe and DSSE predicate/log policy.
- Ship an offline verifier script and golden bundles/replay fixtures to prove determinism.
- Add incident-mode activation/exit records and redaction/tenant isolation guidance for portable bundles.
Merkle recipe (example)
cd bundle
find . -type f ! -name checksums.txt -print0 | sort -z | xargs -0 sha256sum > checksums.txt
sha256sum checksums.txt | awk '{print $1}' > merkle-root.txt
Use the resulting root as the DSSE subject and store checksums.txt inside the bundle.
- Download
bundle.tgzand readinstructions.txt; the first section lists bundle id, root hash, and creation/timestamp information. - Verify
checksums.txtagainst the transferred archive to detect transit corruption. - Use the StellaOps CLI (
stella evidence verify bundle.tgz) or the provenance verifier library to validatesignature.json. - When present, validate the RFC3161 timestamp token with the configured TSA endpoint.
These steps match the offline procedure described in docs/forensics/evidence-locker.md (Portable Evidence section). Update that guide whenever packaging fields change.
Portable bundle (portable-bundle-v1.tgz)
When sealed or air-gapped environments need a redacted evidence artifact, request:
GET /evidence/{bundleId}/portable
The portable archive is deterministic and contains only non-sensitive metadata:
portable-bundle-v1.tgz
├── manifest.json # Canonical manifest (identical to sealed bundle)
├── signature.json # DSSE signature + optional RFC3161 token
├── bundle.json # Redacted metadata (no tenant/storage identifiers)
├── checksums.txt # SHA-256 root + entry checksums
├── instructions-portable.txt # Sealed-mode transfer + verification guidance
└── verify-offline.sh # Offline verification helper script (POSIX shell)
Portable packaging traits:
bundle.jsonexcludes tenant identifiers, storage keys, and free-form descriptions. It addsportableGeneratedAtalong with entry counts and totals for audit purposes.incidentMetadatais preserved only when incident mode injectsincident.*keys into the manifest metadata.verify-offline.shextracts the bundle, validates checksums (usingsha256sum/shasum), surfaces the Merkle root hash, and reminds operators to runstella evidence verify --bundle <archive>.instructions-portable.txtmirrors the sealed documentation but calls out the offline script and redaction constraints.
Portable bundles reuse the same DSSE payload and timestamp, so downstream verifiers can validate signatures without additional configuration. The Evidence Locker tracks the portable storage key separately to honour write-once semantics for both sealed and portable artifacts.
For step-by-step sealed-mode guidance see docs/airgap/portable-evidence.md.