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>
This commit is contained in:
157
backup-sovereign/scripts/99_report.sh
Executable file
157
backup-sovereign/scripts/99_report.sh
Executable file
@@ -0,0 +1,157 @@
|
||||
#!/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) $*"; }
|
||||
|
||||
get_file_size() {
|
||||
local path="$1"
|
||||
if [[ -f "$path" ]]; then
|
||||
stat -c%s "$path"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
local report="$OUTPUT_DIR/audit_report.md"
|
||||
local status="$OUTPUT_DIR/status_matrix.json"
|
||||
local last_run_file="$OUTPUT_DIR/last_run_dir.txt"
|
||||
|
||||
local run_dir="(unknown)"
|
||||
[[ -f "$last_run_file" ]] && run_dir="$(cat "$last_run_file")"
|
||||
|
||||
local root_value="(not generated)"
|
||||
[[ -f "$run_dir/ROOT.txt" ]] && root_value="$(cat "$run_dir/ROOT.txt")"
|
||||
|
||||
local archive_size enc_size
|
||||
archive_size=$(get_file_size "$run_dir/archive.tar.gz")
|
||||
enc_size=$(get_file_size "$run_dir/archive.tar.gz.age")
|
||||
|
||||
local restore_status="NOT COMPLETED"
|
||||
[[ -f "$run_dir/last_restore_dir.txt" ]] && restore_status="PASSED"
|
||||
|
||||
cat > "$report" <<EOF
|
||||
# Backup Sovereign Audit Report
|
||||
|
||||
**Generated:** $(date -Iseconds)
|
||||
**Node:** $NODE_NAME
|
||||
**Run Directory:** $run_dir
|
||||
**Skill Version:** 1.0.0
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This report documents the backup operations performed on **$NODE_NAME**
|
||||
for sovereign EU infrastructure.
|
||||
|
||||
---
|
||||
|
||||
## Backup Artifacts
|
||||
|
||||
| Artifact | Path | Size |
|
||||
|----------|------|------|
|
||||
| Archive | archive.tar.gz | $archive_size bytes |
|
||||
| Encrypted | archive.tar.gz.age | $enc_size bytes |
|
||||
| Manifest | manifest.json | $(get_file_size "$run_dir/manifest.json") bytes |
|
||||
| Proof | PROOF.json | $(get_file_size "$run_dir/PROOF.json") bytes |
|
||||
| ROOT | ROOT.txt | $(get_file_size "$run_dir/ROOT.txt") bytes |
|
||||
|
||||
---
|
||||
|
||||
## Proof Receipt
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| ROOT (BLAKE3) | \`$root_value\` |
|
||||
|
||||
This ROOT value can be anchored via:
|
||||
- merkle-forest skill (aggregate with other proofs)
|
||||
- rfc3161-anchor skill (RFC 3161 timestamp)
|
||||
- eth-anchor / btc-anchor skills (blockchain anchoring)
|
||||
|
||||
---
|
||||
|
||||
## Restore Drill
|
||||
|
||||
| Status | Result |
|
||||
|--------|--------|
|
||||
| Restore Drill | **$restore_status** |
|
||||
|
||||
$(if [[ -f "$run_dir/last_restore_dir.txt" ]]; then
|
||||
echo "Restore location: \`$(cat "$run_dir/last_restore_dir.txt")\`"
|
||||
else
|
||||
echo "**WARNING:** Backup has not been verified via restore drill."
|
||||
echo "Run \`./scripts/50_restore_drill.sh\` to validate recoverability."
|
||||
fi)
|
||||
|
||||
---
|
||||
|
||||
## Verification Results
|
||||
|
||||
$(if [[ -f "$status" ]]; then
|
||||
echo '```json'
|
||||
cat "$status"
|
||||
echo '```'
|
||||
else
|
||||
echo "Status matrix not found. Run 90_verify.sh first."
|
||||
fi)
|
||||
|
||||
---
|
||||
|
||||
## EU Compliance Declaration
|
||||
|
||||
| Aspect | Value |
|
||||
|--------|-------|
|
||||
| Data Residency | EU (Ireland - Dublin) |
|
||||
| GDPR Applicable | Yes (depends on backup content) |
|
||||
| Jurisdiction | Irish Law |
|
||||
| Encryption at Rest | Yes (age) |
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Store encrypted bundle off-node (secondary disk / object store)
|
||||
2. Test restore on a different machine (recommended)
|
||||
3. Anchor ROOT.txt with rfc3161-anchor skill
|
||||
4. Proceed to **disaster-recovery** skill
|
||||
|
||||
---
|
||||
|
||||
## Artifact Locations
|
||||
|
||||
| Artifact | Path |
|
||||
|----------|------|
|
||||
| Archive | $run_dir/archive.tar.gz |
|
||||
| Encrypted Archive | $run_dir/archive.tar.gz.age |
|
||||
| Manifest | $run_dir/manifest.json |
|
||||
| ROOT | $run_dir/ROOT.txt |
|
||||
| Proof | $run_dir/PROOF.json |
|
||||
| Status Matrix | $OUTPUT_DIR/status_matrix.json |
|
||||
| This Report | $OUTPUT_DIR/audit_report.md |
|
||||
|
||||
---
|
||||
|
||||
*Report generated by backup-sovereign skill v1.0.0*
|
||||
*$(date -Iseconds)*
|
||||
EOF
|
||||
|
||||
log_info "Audit report written to $report"
|
||||
echo ""
|
||||
cat "$report"
|
||||
log_info "Completed $SCRIPT_NAME"
|
||||
}
|
||||
|
||||
[[ "${BASH_SOURCE[0]}" == "$0" ]] && main "$@"
|
||||
Reference in New Issue
Block a user