Skip to content

Backup & Restore

Backup Strategy, RTO/RPO Targets, and Recovery Procedures

Document Version: 1.0.0
Last Updated: 2026-02-10


1. Backup Strategy Overview

Component Method Frequency Retention
PostgreSQL pg_dump / Azure Backup Daily + before changes 30 days
Encryption Keys Manual export to secure storage On creation + rotation Permanent
Secrets Vault Copy secrets.vault + vault.key On change + rotation Permanent
Configuration File system copy Before changes 30 days
TLS Certificates File system copy Before rotation Until expired + 90 days
Redis Not backed up (ephemeral cache)

2. RTO/RPO Targets

Scenario RPO (Data Loss) RTO (Downtime)
Database corruption < 24 hours < 4 hours
Complete node failure < 24 hours < 2 hours (K8s) / < 4 hours (on-prem)
Datacenter failure < 1 hour (with sync) < 8 hours
Encryption key loss 0 (keys backed up) < 2 hours
Ransomware / data loss < 24 hours < 8 hours

3. Database Backup

On-Premise (pg_dump)

#!/bin/bash
# mazevault-backup.sh
BACKUP_DIR="/opt/mazevault/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/mazevault_${TIMESTAMP}.sql.gz"

# Create backup
docker exec client-postgres pg_dump \
  -U mazevault \
  -d mazevault \
  --format=custom \
  --compress=9 \
  > "$BACKUP_FILE"

# Verify backup integrity
docker exec client-postgres pg_restore \
  --list "$BACKUP_FILE" > /dev/null 2>&1

if [ $? -eq 0 ]; then
  echo "Backup successful: $BACKUP_FILE"
  # Cleanup old backups (keep 30 days)
  find "$BACKUP_DIR" -name "mazevault_*.sql.gz" -mtime +30 -delete
else
  echo "ERROR: Backup verification failed"
  exit 1
fi

Schedule with cron:

# Daily backup at 2:00 AM
0 2 * * * /opt/mazevault/scripts/mazevault-backup.sh >> /var/log/mazevault-backup.log 2>&1

Azure (Managed Backup)

Azure Database for PostgreSQL Flexible Server provides automated backups:

  • Point-in-Time Restore: Available for any point within the retention period
  • Retention: 7–35 days (configurable)
  • Geo-Redundant Backup: Available for cross-region recovery
# Restore to point in time
az postgres flexible-server restore \
  --resource-group rg-mazevault-prod \
  --name psql-mazevault-restored \
  --source-server psql-mazevault-prod \
  --restore-time "2026-02-09T00:00:00Z"

4. Encryption Key Backup

Critical

Loss of the master encryption key results in permanent loss of all encrypted data. Key backup is the most important backup operation.

If using the encrypted secrets vault (secrets.vault), back up both files:

# On-premise — vault files
cp /opt/mazevault/secrets.vault /secure-backup/secrets.vault.$(date +%Y%m%d)
cp /opt/mazevault/vault.key /secure-backup/vault.key.$(date +%Y%m%d)

# Verify backup integrity
vault-tool list \
  --vault-file /secure-backup/secrets.vault.$(date +%Y%m%d) \
  --key-file /secure-backup/vault.key.$(date +%Y%m%d)

Vault Backup

Store vault.key and secrets.vault backups in physically separate locations. For detailed vault backup/restore procedures, see Encrypted Secrets Vault.

Legacy Key Backup Procedure (.env-based)

  1. Export the master key to an encrypted file:

    # The master key is in the .env file or K8s secret
    # Copy to a secure, offline location
    
    # On-premise
    cp /opt/mazevault/.env /secure-backup/mazevault-env-$(date +%Y%m%d)
    
    # Kubernetes
    kubectl get secret mazevault-master-key -n mazevault -o yaml > \
      /secure-backup/mazevault-master-key-$(date +%Y%m%d).yaml
    

  2. Store in a physically separate, secure location:

  3. Hardware security module (HSM)
  4. Bank safe deposit box
  5. Sealed envelope in secure storage
  6. Multiple copies in different physical locations

Key Backup Verification

Quarterly verify that backup keys can decrypt test data:

# Verify key backup is readable and matches active key
# Compare hash of backed-up key with active key
sha256sum /secure-backup/mazevault-env-latest

5. Configuration Backup

# On-premise configuration backup
tar czf /opt/mazevault/backups/config_$(date +%Y%m%d).tar.gz \
  /opt/mazevault/.env \
  /opt/mazevault/docker-compose.yml \
  /opt/mazevault/certs/ \
  /opt/mazevault/config/

# Kubernetes configuration backup
kubectl get configmap,secret -n mazevault -o yaml > \
  /path/to/backup/mazevault-k8s-config-$(date +%Y%m%d).yaml

6. Restore Procedures

Database Restore (On-Premise)

# Stop the application
docker compose stop backend ocsp-responder

# Restore database
docker exec -i client-postgres pg_restore \
  -U mazevault \
  -d mazevault \
  --clean \
  --if-exists \
  < /opt/mazevault/backups/mazevault_20260210_020000.sql.gz

# Start the application
docker compose start backend ocsp-responder

# Verify health
curl -sk https://localhost/api/v1/health | jq .

Full System Restore (On-Premise)

  1. Prepare new host — Install Docker, Docker Compose per On-Premise Deployment
  2. Restore configuration — Extract config backup to /opt/mazevault/
  3. Restore certificates — Ensure TLS certs are in /opt/mazevault/certs/
  4. Load container images — From offline package or registry
  5. Start infrastructuredocker compose up -d client-postgres client-redis
  6. Restore database — Using pg_restore as shown above
  7. Start applicationdocker compose up -d
  8. Verify — Run health checks, verify secret access, check audit logs

Disaster Recovery Test

Conduct DR tests quarterly:

  1. Provision a test environment
  2. Restore from backup (database + config + keys)
  3. Verify all secrets are accessible and decryptable
  4. Verify certificate operations work correctly
  5. Document test results and any issues