# Offline Proof of Exposure (PoE) Verification Guide _Last updated: 2025-12-23. Owner: CLI Guild._ This guide provides step-by-step instructions for verifying Proof of Exposure artifacts in offline, air-gapped environments. It covers exporting PoE bundles, transferring them securely, and running verification without network access. --- ## 1. Overview ### 1.1 What is Offline PoE Verification? Offline verification allows auditors to validate vulnerability reachability claims without internet access by: - Verifying DSSE signatures against trusted keys - Checking content integrity via cryptographic hashes - Confirming policy bindings - (Optional) Validating Rekor inclusion proofs from cached checkpoints ### 1.2 Use Cases - **Air-gapped environments**: Verify PoE artifacts in isolated networks - **Regulatory compliance**: Provide auditable proof for SOC2, FedRAMP, PCI audits - **Sovereign deployments**: Verify artifacts with regional crypto standards (GOST, SM2) - **Incident response**: Analyze vulnerability reachability offline during security events ### 1.3 Prerequisites **Tools Required:** - `stella` CLI (StellaOps command-line interface) - Trusted public keys for signature verification - (Optional) Rekor checkpoint file for transparency log verification **Knowledge Required:** - Basic understanding of DSSE (Dead Simple Signing Envelope) - Familiarity with container image digests and PURLs - Understanding of CVE identifiers --- ## 2. Quick Start (5-Minute Walkthrough) ### Step 1: Export PoE Artifact **On connected system:** ```bash stella poe export \ --finding CVE-2021-44228:pkg:maven/log4j@2.14.1 \ --scan-id scan-abc123 \ --output ./poe-export/ # Output: # Exported PoE artifacts to ./poe-export/ # - poe.json (4.5 KB) # - poe.json.dsse (2.3 KB) # - trusted-keys.json (1.2 KB) # - rekor-checkpoint.json (0.8 KB) [optional] ``` ### Step 2: Transfer to Offline System ```bash # Create tarball for transfer tar -czf poe-bundle.tar.gz -C ./poe-export . # Transfer via USB, secure file share, or other air-gap bridge # Verify checksum before transfer: sha256sum poe-bundle.tar.gz ``` ### Step 3: Verify on Offline System **On air-gapped system:** ```bash # Extract bundle tar -xzf poe-bundle.tar.gz -C ./verify/ # Run verification stella poe verify \ --poe ./verify/poe.json \ --offline \ --trusted-keys ./verify/trusted-keys.json # Output: # PoE Verification Report # ======================= # ✓ DSSE signature valid (key: scanner-signing-2025) # ✓ Content hash verified # ✓ Policy digest matches # Status: VERIFIED ``` --- ## 3. Detailed Export Workflow ### 3.1 Export Single PoE Artifact **Command:** ```bash stella poe export --finding : --scan-id --output ``` **Example:** ```bash stella poe export \ --finding CVE-2021-44228:pkg:maven/log4j@2.14.1 \ --scan-id scan-abc123 \ --output ./poe-export/ \ --include-rekor-proof ``` **Output Structure:** ``` ./poe-export/ ├── poe.json # Canonical PoE artifact ├── poe.json.dsse # DSSE signature envelope ├── trusted-keys.json # Public keys for verification ├── rekor-checkpoint.json # Rekor transparency log checkpoint └── metadata.json # Export metadata (timestamp, version, etc.) ``` ### 3.2 Export Multiple PoEs (Batch Mode) **Command:** ```bash stella poe export \ --scan-id scan-abc123 \ --all-reachable \ --output ./poe-batch/ ``` **Output Structure:** ``` ./poe-batch/ ├── manifest.json # Index of all PoEs in bundle ├── poe-7a8b9c0d.json # PoE for CVE-2021-44228 ├── poe-7a8b9c0d.json.dsse ├── poe-1a2b3c4d.json # PoE for CVE-2022-XXXXX ├── poe-1a2b3c4d.json.dsse ├── trusted-keys.json └── rekor-checkpoint.json ``` ### 3.3 Export Options | Option | Description | Default | |--------|-------------|---------| | `--finding :` | Specific finding to export | Required (unless --all-reachable) | | `--scan-id ` | Scan identifier | Required | | `--output ` | Output directory | `./poe-export/` | | `--include-rekor-proof` | Include Rekor inclusion proof | `true` | | `--include-subgraph` | Include parent richgraph-v1 | `false` | | `--include-sbom` | Include SBOM artifact | `false` | | `--all-reachable` | Export all reachable findings | `false` | | `--format ` | Archive format | `tar.gz` | --- ## 4. Detailed Verification Workflow ### 4.1 Basic Verification **Command:** ```bash stella poe verify --poe [options] ``` **Example:** ```bash stella poe verify \ --poe ./verify/poe.json \ --offline \ --trusted-keys ./verify/trusted-keys.json ``` **Verification Steps Performed:** 1. ✓ Load PoE artifact and DSSE envelope 2. ✓ Verify DSSE signature against trusted keys 3. ✓ Compute BLAKE3-256 hash and verify content integrity 4. ✓ Parse PoE structure and validate schema 5. ✓ Display verification results ### 4.2 Advanced Verification (with Policy Binding) **Command:** ```bash stella poe verify \ --poe ./verify/poe.json \ --offline \ --trusted-keys ./verify/trusted-keys.json \ --check-policy sha256:abc123... \ --verbose ``` **Additional Checks:** - ✓ Verify policy digest matches expected value - ✓ Validate policy evaluation timestamp is recent - ✓ Display policy details (policyId, version) ### 4.3 Rekor Inclusion Verification (Offline) **Command:** ```bash stella poe verify \ --poe ./verify/poe.json \ --offline \ --trusted-keys ./verify/trusted-keys.json \ --rekor-checkpoint ./verify/rekor-checkpoint.json ``` **Rekor Verification:** - ✓ Load cached Rekor checkpoint (from last online sync) - ✓ Verify inclusion proof against checkpoint - ✓ Validate log index and tree size - ✓ Confirm timestamp is within acceptable window ### 4.4 Verification Options | Option | Description | Required | |--------|-------------|----------| | `--poe ` | PoE file path or hash | Yes | | `--offline` | Enable offline mode (no network) | Recommended | | `--trusted-keys ` | Path to trusted keys JSON | Yes (offline mode) | | `--check-policy ` | Verify policy digest | No | | `--rekor-checkpoint ` | Cached Rekor checkpoint | No | | `--verbose` | Detailed output | No | | `--output ` | Output format: `table\|json\|summary` | `table` | | `--strict` | Fail on warnings (e.g., expired keys) | No | --- ## 5. Verification Output Formats ### 5.1 Table Format (Default) ``` PoE Verification Report ======================= PoE Hash: blake3:7a8b9c0d1e2f3a4b... Vulnerability: CVE-2021-44228 Component: pkg:maven/log4j@2.14.1 Build ID: gnu-build-id:5f0c7c3c... Generated: 2025-12-23T10:00:00Z Verification Checks: ✓ DSSE signature valid (key: scanner-signing-2025) ✓ Content hash verified ✓ Policy digest matches (sha256:abc123...) ✓ Schema validation passed Subgraph Summary: Nodes: 8 functions Edges: 12 call relationships Paths: 3 distinct paths (shortest: 4 hops) Entry Points: main(), UserController.handleRequest() Sink: org.apache.logging.log4j.Logger.error() Guard Predicates: - feature:dark-mode (1 edge) - platform:linux (0 edges) Status: VERIFIED ``` ### 5.2 JSON Format ```bash stella poe verify --poe ./poe.json --offline --output json > result.json ``` **Output:** ```json { "status": "verified", "poeHash": "blake3:7a8b9c0d1e2f3a4b...", "subject": { "vulnId": "CVE-2021-44228", "componentRef": "pkg:maven/log4j@2.14.1", "buildId": "gnu-build-id:5f0c7c3c..." }, "checks": { "dsseSignature": {"passed": true, "keyId": "scanner-signing-2025"}, "contentHash": {"passed": true, "algorithm": "blake3"}, "policyBinding": {"passed": true, "digest": "sha256:abc123..."}, "schemaValidation": {"passed": true, "version": "v1"} }, "subgraph": { "nodeCount": 8, "edgeCount": 12, "pathCount": 3, "shortestPathLength": 4 }, "timestamp": "2025-12-23T11:00:00Z" } ``` ### 5.3 Summary Format (Concise) ```bash stella poe verify --poe ./poe.json --offline --output summary ``` **Output:** ``` CVE-2021-44228 in pkg:maven/log4j@2.14.1: VERIFIED Hash: blake3:7a8b9c0d... Paths: 3 (4-6 hops) Signature: ✓ scanner-signing-2025 ``` --- ## 6. Trusted Keys Management ### 6.1 Trusted Keys Format **File:** `trusted-keys.json` ```json { "keys": [ { "keyId": "scanner-signing-2025", "algorithm": "ECDSA-P256", "publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEw...\n-----END PUBLIC KEY-----", "validFrom": "2025-01-01T00:00:00Z", "validUntil": "2025-12-31T23:59:59Z", "purpose": "Scanner signing", "revoked": false }, { "keyId": "scanner-signing-2024", "algorithm": "ECDSA-P256", "publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEw...\n-----END PUBLIC KEY-----", "validFrom": "2024-01-01T00:00:00Z", "validUntil": "2024-12-31T23:59:59Z", "purpose": "Scanner signing (previous year)", "revoked": false } ], "updatedAt": "2025-12-23T00:00:00Z" } ``` ### 6.2 Key Distribution **Online Distribution:** ```bash # Fetch latest trusted keys from StellaOps backend stella keys fetch --output ./trusted-keys.json ``` **Offline Distribution:** - Include `trusted-keys.json` in offline update kits - Distribute via secure channels (USB, secure file share) - Verify checksum before use **Key Pinning (Strict Mode):** ```bash # Only accept signatures from specific key ID stella poe verify \ --poe ./poe.json \ --offline \ --trusted-keys ./trusted-keys.json \ --pin-key scanner-signing-2025 ``` ### 6.3 Key Rotation Handling **Scenario:** PoE signed with old key (scanner-signing-2024), but you only have new key (scanner-signing-2025). **Solution:** 1. Include both old and new keys in `trusted-keys.json` 2. Verification will succeed if any trusted key validates signature 3. (Optional) Set `--strict` to reject expired keys **Example:** ```bash stella poe verify \ --poe ./poe.json \ --offline \ --trusted-keys ./trusted-keys.json # Output: ✓ DSSE signature valid (key: scanner-signing-2024, EXPIRED but trusted) ``` --- ## 7. Rekor Checkpoint Verification ### 7.1 What is a Rekor Checkpoint? A Rekor checkpoint is a cryptographically signed snapshot of the transparency log state at a specific point in time. It includes: - Log size (total entries) - Root hash (Merkle tree root) - Timestamp - Signature by Rekor log operator ### 7.2 Checkpoint Format **File:** `rekor-checkpoint.json` ```json { "origin": "rekor.sigstore.dev", "size": 50000000, "hash": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", "timestamp": "2025-12-23T00:00:00Z", "signature": "-----BEGIN SIGNATURE-----\n...\n-----END SIGNATURE-----" } ``` ### 7.3 Offline Rekor Verification **Command:** ```bash stella poe verify \ --poe ./poe.json \ --offline \ --rekor-checkpoint ./rekor-checkpoint.json ``` **Verification Steps:** 1. Load PoE and DSSE envelope 2. Load cached Rekor checkpoint 3. Load Rekor inclusion proof (from `poe.json.rekor`) 4. Verify inclusion proof against checkpoint root hash 5. Confirm log index is within checkpoint size 6. Display verification result **Output:** ``` Rekor Verification: ✓ Inclusion proof valid ✓ Log index: 12345678 (within checkpoint size: 50000000) ✓ Checkpoint timestamp: 2025-12-23T00:00:00Z ✓ Checkpoint signature valid Status: VERIFIED ``` --- ## 8. Troubleshooting ### 8.1 Signature Verification Failed **Error:** ``` ✗ DSSE signature verification failed Reason: Signature does not match any trusted key ``` **Possible Causes:** 1. **Wrong trusted keys file**: Ensure `trusted-keys.json` contains the signing key 2. **Corrupted artifact**: Re-export PoE from source 3. **Key ID mismatch**: Check `keyId` in DSSE envelope matches trusted keys **Solution:** ```bash # Inspect DSSE envelope to see which key was used jq '.signatures[0].keyid' poe.json.dsse # Verify key is in trusted-keys.json jq '.keys[] | select(.keyId == "scanner-signing-2025")' trusted-keys.json # If key is missing, re-export with correct key or update trusted keys ``` ### 8.2 Hash Mismatch **Error:** ``` ✗ Content hash verification failed Expected: blake3:7a8b9c0d... Computed: blake3:1a2b3c4d... ``` **Possible Causes:** 1. **Corrupted file**: File was modified during transfer 2. **Encoding issue**: Line ending conversion (CRLF vs LF) 3. **Wrong file**: Exported different PoE than expected **Solution:** ```bash # Verify file integrity with checksum sha256sum poe.json # Re-export PoE from source with checksum verification stella poe export --finding CVE-2021-44228:pkg:maven/log4j@2.14.1 \ --scan-id scan-abc123 \ --output ./poe-export/ \ --verify-checksum ``` ### 8.3 Policy Digest Mismatch **Error:** ``` ✗ Policy digest verification failed Expected: sha256:abc123... Found: sha256:def456... ``` **Possible Causes:** 1. **Policy version changed**: PoE was generated with different policy version 2. **Wrong policy digest provided**: CLI argument incorrect **Solution:** ```bash # Check PoE metadata for policy digest jq '.metadata.policy.policyDigest' poe.json # Verify against expected policy version # If mismatch is expected (policy updated), omit --check-policy flag stella poe verify --poe ./poe.json --offline ``` ### 8.4 Rekor Checkpoint Too Old **Warning:** ``` ⚠ Rekor checkpoint is outdated Checkpoint timestamp: 2025-01-15T00:00:00Z PoE generated: 2025-12-23T10:00:00Z ``` **Possible Causes:** 1. **Stale checkpoint**: Checkpoint was cached before PoE was generated 2. **Clock skew**: System clocks are out of sync **Solution:** ```bash # Accept warning (PoE is still valid, just can't verify Rekor inclusion) stella poe verify --poe ./poe.json --offline --skip-rekor # Or fetch updated checkpoint (requires online access) stella rekor checkpoint-fetch --output ./rekor-checkpoint.json ``` --- ## 9. Batch Verification ### 9.1 Verify All PoEs in Directory **Command:** ```bash stella poe verify-batch \ --input ./poe-batch/ \ --offline \ --trusted-keys ./trusted-keys.json \ --output ./verification-results.json ``` **Output:** ```json { "totalPoEs": 15, "verified": 14, "failed": 1, "results": [ {"poeHash": "blake3:7a8b9c0d...", "status": "verified", "vulnId": "CVE-2021-44228"}, {"poeHash": "blake3:1a2b3c4d...", "status": "failed", "vulnId": "CVE-2022-XXXXX", "error": "Signature verification failed"}, ... ] } ``` ### 9.2 Parallel Verification **Command:** ```bash stella poe verify-batch \ --input ./poe-batch/ \ --offline \ --trusted-keys ./trusted-keys.json \ --parallel 4 # Use 4 worker threads ``` **Performance:** | PoE Count | Serial Time | Parallel Time (4 threads) | Speedup | |-----------|-------------|---------------------------|---------| | 10 | 5s | 2s | 2.5x | | 50 | 25s | 8s | 3.1x | | 100 | 50s | 15s | 3.3x | --- ## 10. Best Practices ### 10.1 Security Best Practices 1. **Verify checksums** before and after transfer: ```bash sha256sum poe-bundle.tar.gz > poe-bundle.tar.gz.sha256 ``` 2. **Use strict mode** in production: ```bash stella poe verify --poe ./poe.json --offline --strict ``` 3. **Pin keys** for critical environments: ```bash stella poe verify --poe ./poe.json --pin-key scanner-signing-2025 ``` 4. **Rotate keys** every 90 days and update `trusted-keys.json` 5. **Archive verified PoEs** for audit trails ### 10.2 Operational Best Practices 1. **Export PoEs regularly**: Include in CI/CD pipeline 2. **Test offline verification** before relying on it for audits 3. **Document key rotation** procedures 4. **Automate batch verification** for large datasets 5. **Monitor verification failures** and investigate root causes --- ## 11. Example Workflows ### 11.1 SOC2 Audit Preparation **Goal:** Prepare PoE artifacts for SOC2 auditor review **Steps:** ```bash # 1. Export all PoEs for production images stella poe export \ --all-reachable \ --scan-id prod-release-v42 \ --output ./audit-bundle/ \ --include-rekor-proof \ --include-sbom # 2. Create audit package tar -czf soc2-audit-$(date +%Y%m%d).tar.gz -C ./audit-bundle . # 3. Generate checksum manifest sha256sum soc2-audit-*.tar.gz > checksum.txt # 4. Provide to auditor with verification instructions cp OFFLINE_POE_VERIFICATION.md ./audit-package/ ``` **Auditor Workflow:** ```bash # 1. Extract bundle tar -xzf soc2-audit-20251223.tar.gz -C ./verify/ # 2. Verify all PoEs stella poe verify-batch \ --input ./verify/ \ --offline \ --trusted-keys ./verify/trusted-keys.json \ --output ./audit-results.json # 3. Review results jq '.verified, .failed' ./audit-results.json ``` ### 11.2 Incident Response Investigation **Goal:** Analyze vulnerability reachability during security incident **Steps:** ```bash # 1. Export PoE for suspected CVE stella poe export \ --finding CVE-2024-XXXXX:pkg:npm/vulnerable-lib@1.0.0 \ --scan-id incident-scan-123 \ --output ./incident-poe/ # 2. Verify offline (air-gapped IR environment) stella poe verify \ --poe ./incident-poe/poe.json \ --offline \ --verbose # 3. Analyze call paths jq '.subgraph.edges' ./incident-poe/poe.json # 4. Identify entry points jq '.subgraph.entryRefs' ./incident-poe/poe.json ``` --- ## 12. Cross-References - **PoE Specification:** `src/Attestor/POE_PREDICATE_SPEC.md` - **Subgraph Extraction:** `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/SUBGRAPH_EXTRACTION.md` - **Sprint Plan:** `docs/implplan/SPRINT_3500_0001_0001_proof_of_exposure_mvp.md` - **Advisory:** `docs/product-advisories/23-Dec-2026 - Binary Mapping as Attestable Proof.md` --- _Last updated: 2025-12-23. See Sprint 3500.0001.0001 for implementation plan._