# VEX Signature Verification: Offline Mode **Sprint:** SPRINT_1227_0004_0001_BE_signature_verification **Task:** T11 - Document offline mode with bundled trust anchors **Date:** 2025-12-28 --- ## Overview This document describes how to configure VEX signature verification for air-gapped (offline) deployments where network access to public trust infrastructure (Sigstore, Fulcio, Rekor) is unavailable. --- ## Offline Mode Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ Air-Gapped Environment │ │ │ │ ┌───────────────┐ ┌────────────────────────────────┐ │ │ │ VEX Documents │────▶│ ProductionVexSignatureVerifier │ │ │ └───────────────┘ └────────────────────────────────┘ │ │ │ │ │ ┌──────────────┴────────────────┐ │ │ ▼ ▼ │ │ ┌─────────────────────────┐ ┌─────────────────────┐ │ │ │ Bundled Trust Anchors │ │ Bundled Issuer Dir │ │ │ │ /var/stellaops/trust/ │ │ /var/stellaops/ │ │ │ │ ├── fulcio-root.pem │ │ bundles/issuers.json│ │ │ │ ├── sigstore-root.pem │ └─────────────────────┘ │ │ │ └── internal-ca.pem │ │ │ └─────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Configuration ### 1. Enable Offline Mode **File:** `etc/excititor.yaml` ```yaml VexSignatureVerification: Enabled: true DefaultProfile: "world" OfflineMode: true # Critical: Enable offline verification # Offline-specific settings OfflineBundle: Enabled: true BundlePath: "/var/stellaops/bundles" RefreshOnStartup: false # Trust anchors for signature verification TrustAnchors: Fulcio: - "/var/stellaops/trust/fulcio-root.pem" - "/var/stellaops/trust/fulcio-intermediate.pem" Sigstore: - "/var/stellaops/trust/sigstore-root.pem" Internal: - "/var/stellaops/trust/internal-ca.pem" - "/var/stellaops/trust/internal-intermediate.pem" # IssuerDirectory in offline mode IssuerDirectory: OfflineBundle: "/var/stellaops/bundles/issuers.json" FallbackToBundle: true # ServiceUrl not needed in offline mode ``` ### 2. Directory Structure ``` /var/stellaops/ ├── bundles/ │ ├── issuers.json # Issuer directory bundle │ ├── revocations.json # Key revocation data │ └── tuf-metadata/ # TUF metadata for updates │ ├── root.json │ ├── targets.json │ └── snapshot.json ├── trust/ │ ├── fulcio-root.pem # Sigstore Fulcio root CA │ ├── fulcio-intermediate.pem │ ├── sigstore-root.pem # Sigstore root │ ├── rekor-pubkey.pem # Rekor public key │ ├── internal-ca.pem # Internal enterprise CA │ └── internal-intermediate.pem └── cache/ └── verification-cache.db # Local verification cache ``` --- ## Bundle Preparation ### 1. Download Trust Anchors Run this on a connected machine to prepare the bundle: ```bash #!/bin/bash # prepare-offline-bundle.sh BUNDLE_DIR="./offline-bundle" mkdir -p "$BUNDLE_DIR/trust" "$BUNDLE_DIR/bundles" # Download Sigstore trust anchors echo "Downloading Sigstore trust anchors..." curl -sSL https://fulcio.sigstore.dev/api/v2/trustBundle \ -o "$BUNDLE_DIR/trust/fulcio-root.pem" curl -sSL https://rekor.sigstore.dev/api/v1/log/publicKey \ -o "$BUNDLE_DIR/trust/rekor-pubkey.pem" # Download TUF metadata echo "Downloading TUF metadata..." cosign initialize --mirror=https://tuf-repo.sigstore.dev \ --root="$BUNDLE_DIR/bundles/tuf-metadata" # Export issuer directory echo "Exporting issuer directory..." stellaops-cli issuer-directory export \ --format json \ --output "$BUNDLE_DIR/bundles/issuers.json" # Export revocation data echo "Exporting revocation data..." stellaops-cli revocations export \ --format json \ --output "$BUNDLE_DIR/bundles/revocations.json" # Create manifest echo "Creating bundle manifest..." cat > "$BUNDLE_DIR/manifest.json" <