# Offline Verification Playbook (EB9) Purpose: allow auditors to validate Evidence Locker bundles without network access, using only POSIX tools. Applies to both sealed `bundle.tgz` and portable `portable-bundle-v1.tgz`. ## Prerequisites - `tar`, `sha256sum` (or `shasum`), `awk`, `base64`. - Optional: `jq` for schema validation; `cosign` or `stella` CLI for DSSE verification if pre-loaded. ## Quick steps (sealed bundle) 1) `tar -xzf bundle.tgz -C /tmp/bundle` 2) `cd /tmp/bundle` 3) Validate checksums: `sha256sum -c checksums.txt` 4) Derive Merkle root (matches DSSE subject): `sha256sum checksums.txt | awk '{print $1}'` 5) Validate manifest against schema (if `jq` present): `jq -e 'input | type=="object"' manifest.json >/dev/null` 6) Verify DSSE envelope (optional but recommended): - `cat manifest.json | base64 | cosign verify-blob --key cosign.pub --bundle signature.json --bundleType dsse` - or `stella evidence verify --bundle ../bundle.tgz --offline` once CLI supports offline mode. ## Quick steps (portable bundle) Same as sealed, plus confirm redaction: - `jq -e 'has(\"redaction\") and .redaction.portable==true' manifest.json >/dev/null` (if `jq` available) - Confirm no tenant identifiers in `bundle.json` and `manifest.json`. ## Embeddable verifier script Place the following script into `verify-offline.sh` when assembling portable bundles. It exits non-zero on any mismatch and prints the Merkle root used as DSSE subject. ```bash #!/usr/bin/env bash set -euo pipefail BUNDLE="${1:-bundle.tgz}" WORKDIR="$(mktemp -d)" cleanup() { rm -rf "$WORKDIR"; } trap cleanup EXIT tar -xzf "$BUNDLE" -C "$WORKDIR" cd "$WORKDIR" sha256sum -c checksums.txt MERKLE=$(sha256sum checksums.txt | awk '{print $1}') printf "merkle_root=%s\n" "$MERKLE" if command -v jq >/dev/null; then jq -e 'type=="object" and has("entries")' manifest.json >/dev/null fi ``` ## Fixtures - Golden bundles and replay records live under `tests/EvidenceLocker/Bundles/Golden/`. - Expected Merkle roots and DSSE payload digests should be recorded alongside each fixture to keep CI deterministic. ## References - Manifest schema: `docs/modules/evidence-locker/schemas/bundle.manifest.schema.json` - Checksums schema: `docs/modules/evidence-locker/schemas/checksums.schema.json` - Merkle recipe: see `docs/modules/evidence-locker/bundle-packaging.md`