Files
vm-skills/backup-sovereign/scripts/30_generate_proof.sh
Vault Sovereign eac77ef7b4 Initial commit: VaultMesh Skills collection
Collection of operational skills for VaultMesh infrastructure including:
- backup-sovereign: Backup and recovery operations
- btc-anchor: Bitcoin anchoring
- cloudflare-tunnel-manager: Cloudflare tunnel management
- container-registry: Container registry operations
- disaster-recovery: Disaster recovery procedures
- dns-sovereign: DNS management
- eth-anchor: Ethereum anchoring
- gitea-bootstrap: Gitea setup and configuration
- hetzner-bootstrap: Hetzner server provisioning
- merkle-forest: Merkle tree operations
- node-hardening: Node security hardening
- operator-bootstrap: Operator initialization
- proof-verifier: Cryptographic proof verification
- rfc3161-anchor: RFC3161 timestamping
- secrets-vault: Secrets management

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 00:25:00 +00:00

97 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# === METADATA ===
SCRIPT_NAME="$(basename "$0")"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_ROOT="$(dirname "$SCRIPT_DIR")"
# === CONFIGURATION ===
: "${OUTPUT_DIR:=$SKILL_ROOT/outputs}"
: "${NODE_NAME:=node-a}"
# === FUNCTIONS ===
log_info() { echo "[INFO] $(date -Iseconds) $*"; }
log_error() { echo "[ERROR] $(date -Iseconds) $*" >&2; }
die() { log_error "$@"; exit 1; }
b3_file() {
if command -v b3sum &>/dev/null; then
b3sum "$1" | awk '{print $1}'
else
blake3 "$1"
fi
}
b3_string() {
if command -v b3sum &>/dev/null; then
echo -n "$1" | b3sum | awk '{print $1}'
else
echo -n "$1" | blake3
fi
}
main() {
local last_run_file="$OUTPUT_DIR/last_run_dir.txt"
[[ -f "$last_run_file" ]] || die "No last run pointer. Run 11_backup_apply.sh first."
local run_dir
run_dir="$(cat "$last_run_file")"
local manifest="$run_dir/manifest.json"
[[ -f "$manifest" ]] || die "Missing manifest: $manifest"
# Find encrypted archive
local encrypted=""
if [[ -f "$run_dir/archive.tar.gz.age" ]]; then
encrypted="$run_dir/archive.tar.gz.age"
else
die "Missing encrypted archive. Run 21_encrypt_apply.sh first."
fi
log_info "Generating proof receipts..."
log_info "Run directory: $run_dir"
# Compute BLAKE3 hashes
local manifest_b3 encrypted_b3
manifest_b3=$(b3_file "$manifest")
encrypted_b3=$(b3_file "$encrypted")
log_info "Manifest BLAKE3: $manifest_b3"
log_info "Encrypted BLAKE3: $encrypted_b3"
# Compute ROOT = BLAKE3(manifest_b3 || encrypted_b3)
# Using stable text concatenation
local concat root_b3
concat="${manifest_b3}${encrypted_b3}"
root_b3=$(b3_string "$concat")
log_info "ROOT BLAKE3: $root_b3"
# Write ROOT.txt
echo "$root_b3" > "$run_dir/ROOT.txt"
log_info "Wrote: $run_dir/ROOT.txt"
# Write PROOF.json
cat > "$run_dir/PROOF.json" <<EOF
{
"version": 1,
"node": "$NODE_NAME",
"created_at": "$(date -Iseconds)",
"artifacts": {
"manifest_blake3": "$manifest_b3",
"encrypted_archive_blake3": "$encrypted_b3",
"root_blake3": "$root_b3"
},
"computation": "ROOT = BLAKE3(manifest_blake3 || encrypted_archive_blake3)",
"notes": "ROOT can be anchored via merkle-forest/rfc3161-anchor skills."
}
EOF
log_info "Wrote: $run_dir/PROOF.json"
log_info "Proof generation complete."
log_info "Next: ./scripts/40_verify_backup.sh"
}
[[ "${BASH_SOURCE[0]}" == "$0" ]] && main "$@"