#!/bin/bash # ----------------------------------------------------------------------------- # bootstrap-trust-offline.sh # Sprint: SPRINT_20260125_003_Attestor_trust_workflows_conformance # Task: WORKFLOW-001 - Create bootstrap workflow script # Description: Initialize trust for air-gapped StellaOps deployment # ----------------------------------------------------------------------------- set -euo pipefail RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_step() { echo -e "${BLUE}[STEP]${NC} $1"; } usage() { echo "Usage: $0 [options]" echo "" echo "Initialize trust for an air-gapped StellaOps deployment." echo "" echo "Arguments:" echo " trust-bundle Path to trust bundle (tar.zst or directory)" echo "" echo "Options:" echo " --key-dir DIR Directory for signing keys (default: /etc/stellaops/keys)" echo " --reject-if-stale D Reject bundle if older than D (e.g., 7d, 24h)" echo " --skip-keygen Skip signing key generation" echo " --force Force import even if validation fails" echo " -h, --help Show this help message" echo "" echo "Example:" echo " $0 /media/usb/trust-bundle-2026-01-25.tar.zst" exit 1 } BUNDLE_PATH="" KEY_DIR="/etc/stellaops/keys" REJECT_STALE="" SKIP_KEYGEN=false FORCE=false while [[ $# -gt 0 ]]; do case $1 in --key-dir) KEY_DIR="$2"; shift 2 ;; --reject-if-stale) REJECT_STALE="$2"; shift 2 ;; --skip-keygen) SKIP_KEYGEN=true; shift ;; --force) FORCE=true; shift ;; -h|--help) usage ;; -*) log_error "Unknown option: $1"; usage ;; *) if [[ -z "$BUNDLE_PATH" ]]; then BUNDLE_PATH="$1" else log_error "Unexpected argument: $1" usage fi shift ;; esac done if [[ -z "$BUNDLE_PATH" ]]; then log_error "Trust bundle path is required" usage fi if [[ ! -e "$BUNDLE_PATH" ]]; then log_error "Trust bundle not found: $BUNDLE_PATH" exit 1 fi echo "" echo "================================================" echo " StellaOps Offline Trust Bootstrap" echo "================================================" echo "" log_info "Trust Bundle: $BUNDLE_PATH" log_info "Key Directory: $KEY_DIR" if [[ -n "$REJECT_STALE" ]]; then log_info "Staleness Threshold: $REJECT_STALE" fi echo "" # Step 1: Generate signing keys (if using local keys) if [[ "$SKIP_KEYGEN" != "true" ]]; then log_step "Step 1: Generating signing keys..." mkdir -p "$KEY_DIR" chmod 700 "$KEY_DIR" if [[ ! -f "$KEY_DIR/signing-key.pem" ]]; then openssl ecparam -name prime256v1 -genkey -noout -out "$KEY_DIR/signing-key.pem" chmod 600 "$KEY_DIR/signing-key.pem" log_info "Generated signing key: $KEY_DIR/signing-key.pem" else log_info "Signing key already exists: $KEY_DIR/signing-key.pem" fi else log_step "Step 1: Skipping key generation (--skip-keygen)" fi # Step 2: Import trust bundle log_step "Step 2: Importing trust bundle..." IMPORT_ARGS="--verify-manifest" if [[ -n "$REJECT_STALE" ]]; then IMPORT_ARGS="$IMPORT_ARGS --reject-if-stale $REJECT_STALE" fi if [[ "$FORCE" == "true" ]]; then IMPORT_ARGS="$IMPORT_ARGS --force" fi stella trust import "$BUNDLE_PATH" $IMPORT_ARGS if [[ $? -ne 0 ]]; then log_error "Failed to import trust bundle" exit 1 fi log_info "Trust bundle imported successfully" # Step 3: Verify trust state log_step "Step 3: Verifying trust state..." stella trust status --show-keys if [[ $? -ne 0 ]]; then log_error "Failed to verify trust status" exit 1 fi # Step 4: Test offline verification log_step "Step 4: Testing offline verification capability..." # Check that we have TUF metadata CACHE_DIR="${HOME}/.local/share/StellaOps/TufCache" if [[ -f "$CACHE_DIR/root.json" ]] && [[ -f "$CACHE_DIR/timestamp.json" ]]; then log_info "TUF metadata present" else log_warn "TUF metadata may be incomplete" fi # Check for tiles (if snapshot included them) if [[ -d "$CACHE_DIR/tiles" ]]; then TILE_COUNT=$(find "$CACHE_DIR/tiles" -name "*.tile" 2>/dev/null | wc -l) log_info "Tiles cached: $TILE_COUNT" fi echo "" echo "================================================" echo -e "${GREEN} Offline Bootstrap Complete!${NC}" echo "================================================" echo "" log_info "Trust state imported to: $CACHE_DIR" log_info "Signing key (if generated): $KEY_DIR/signing-key.pem" echo "" log_info "This system can now verify attestations offline using the imported trust state." log_warn "Remember to periodically update the trust bundle to maintain freshness." echo "" log_info "To update trust state:" echo " 1. On connected system: stella trust snapshot export --out bundle.tar.zst" echo " 2. Transfer bundle to this system" echo " 3. Run: $0 bundle.tar.zst" echo ""