up
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-24 07:52:25 +02:00
parent 5970f0d9bd
commit 150b3730ef
215 changed files with 8119 additions and 740 deletions

View File

@@ -1,90 +1,27 @@
# Portable Evidence Bundles (Sealed/Air-Gapped)
# Portable Evidence Bundles (DOCS-AIRGAP-58-004)
> Sprint 160 · Task EVID-OBS-60-001
> Audience: Evidence Locker operators, Air-Gap controllers, incident responders
Guidance for exporting/importing portable evidence bundles across enclaves.
Portable bundles let operators hand off sealed evidence across enclaves without exposing tenant identifiers or internal storage coordinates. The Evidence Locker produces a deterministic archive (`portable-bundle-v1.tgz`) that carries the manifest + signature alongside redacted metadata, checksum manifest, and an offline verification script.
## Bundle contents
- Evidence payloads (VEX observations/linksets) as NDJSON.
- Timeline events and attestation DSSE envelopes.
- Manifest with `bundleId`, `source`, `tenant`, `createdAt`, `files[]`, `dsseEnvelopeHash` (optional).
## 1. When to use the portable flow
## Export
- Produce from Evidence Locker/Excititor with deterministic ordering and SHA-256 hashes.
- Include Merkle root over evidence files; store in manifest.
- Sign manifest (DSSE) when trust roots available.
- **Sealed mode exports.** Regulatory or incident response teams that cannot access the primary enclave directly.
- **Chain-of-custody transfers.** Moving evidence into offline review systems while keeping the DSSE provenance intact.
- **Break-glass rehearsals.** Validating incident response playbooks without exposing internal bundle metadata.
## Import
- Verify manifest hash, Merkle root, and DSSE signature offline.
- Enforce tenant scoping; refuse cross-tenant bundles.
- Emit timeline event upon successful import.
Avoid portable bundles for regular intra-enclave automation; the full `bundle.tgz` already carries richer metadata for automated tooling.
## Constraints
- No external lookups; verification uses bundled roots.
- Max size per bundle configurable; default 500MB.
- Keep file paths UTF-8 and slash-separated; avoid host-specific metadata.
## 2. Generating the bundle
1. Seal the evidence bundle as usual (`POST /evidence/snapshot` or via CLI).
2. Request the portable artefact using the new endpoint:
```
GET /evidence/{bundleId}/portable
Scope: evidence:read
```
Response headers mirror the standard download (`application/gzip`, `Content-Disposition: attachment; filename="portable-evidence-bundle-{bundleId}.tgz"`).
The Evidence Locker caches the portable archive using write-once semantics. Subsequent requests reuse the existing object and the audit log records whether the file was newly created or served from cache.
## 3. Archive layout
```
portable-bundle-v1.tgz
├── manifest.json # Canonical bundle manifest (identical to sealed bundle)
├── signature.json # DSSE signature + optional RFC3161 timestamp (base64 token)
├── bundle.json # Redacted metadata (bundleId, kind, rootHash, timestamps, incidentMetadata)
├── checksums.txt # Merkle root + per-entry SHA-256 digests
├── instructions-portable.txt # Human-readable guidance for sealed transfers
└── verify-offline.sh # POSIX shell helper (extract + checksum verify + reminder to run DSSE verification)
```
Redaction rules:
- No tenant identifiers, storage keys, descriptions, or free-form metadata.
- Incident metadata is retained *only* under the `incidentMetadata` object (`incident.mode`, `incident.changedAt`, etc.).
- `portableGeneratedAt` records when the archive was produced so downstream systems can reason about freshness.
## 4. Offline verification workflow
1. Copy `portable-bundle-v1.tgz` into the sealed environment (USB, sneaker-net, etc.).
2. Run the included helper from a POSIX shell:
```sh
chmod +x verify-offline.sh
./verify-offline.sh portable-bundle-v1.tgz
```
The script:
- extracts the archive into a temporary directory,
- validates `checksums.txt` using `sha256sum` (or `shasum -a 256`), and
- prints the Merkle root hash from `bundle.json`.
3. Complete provenance verification:
- Preferred: `stella evidence verify --bundle portable-bundle-v1.tgz`
- Alternative: supply `manifest.json` and `signature.json` to the evidence verifier library.
4. Record the verification output (root hash, timestamp) with the receiving enclaves evidence locker or incident ticket.
> **Note:** The DSSE payload is unchanged from the sealed bundle, so existing verification tooling does not need special handling for portable archives.
## 5. Importing into the receiving enclave
1. Upload the archive to the target Evidence Locker or attach it to the incident record.
2. Store the checksum report generated by `verify-offline.sh` alongside the archive.
3. If downstream automation needs enriched metadata, attach a private note referencing the original bundles tenant context—the portable archive intentionally omits it.
## 6. Troubleshooting
| Symptom | Likely cause | Remediation |
|--------|--------------|-------------|
| `verify-offline.sh` reports checksum failures | Transfer corruption | Re-transfer artefact; run `sha256sum portable-bundle-v1.tgz` on both sides and compare. |
| `stella evidence verify` cannot reach TSA | Sealed environment lacks TSA connectivity | Verification still succeeds using DSSE signature; capture the missing TSA warning in the import log. |
| `/portable` endpoint returns 400 | Bundle not yet sealed or signature missing | Wait for sealing to complete; ensure DSSE signing is enabled. |
| `/portable` returns 404 | Bundle not found or tenant mismatch | Confirm DPoP scope and tenant claim; refresh bundle status via `GET /evidence/{id}`. |
## 7. Change management
- Portable bundle versioning is encoded in the filename (`portable-bundle-v1.tgz`). When content or script behaviour changes, bump the version and announce in release notes.
- Any updates to `verify-offline.sh` must remain POSIX-sh compatible and avoid external dependencies beyond `tar`, `sha256sum`/`shasum`, and standard coreutils.
- Remember to update this guide and the bundle packaging dossier (`docs/modules/evidence-locker/bundle-packaging.md`) when fields or workflows change.
## Determinism
- Sort files lexicographically; use ISO-8601 UTC timestamps.
- Avoid re-compressing files; if tar is used, set deterministic headers (uid/gid=0, mtime=0).