Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/lamassuiot/lamassuiot/llms.txt

Use this file to discover all available pages before exploring further.

Regular backups are critical for protecting your PKI infrastructure and device inventory. This page describes backup strategies, procedures, and disaster recovery for Lamassu IoT deployments.

Backup Strategy

What to Back Up

A complete Lamassu backup includes:

Database

PostgreSQL containing all CAs, certificates, devices, and metadata.

Crypto Engine Keys

CA private keys stored in Vault, AWS KMS, or PKCS#11 HSM.

Configuration

Service configuration files, environment variables, and secrets.

TLS Certificates

Service TLS certificates for HTTPS endpoints.
CA private keys are the most critical assets. Loss of CA keys means inability to issue or revoke certificates. Secure backup of crypto engines is paramount.

Backup Frequency

ComponentFrequencyRetention
DatabaseHourly30 days
Crypto engine (Vault)Daily90 days
ConfigurationOn change90 days
Full system snapshotWeekly12 weeks

Database Backup

PostgreSQL Backup

Lamassu uses PostgreSQL with multiple schemas (or databases) for different services:
  • ca - Certificate Authority data
  • devicemanager - Device inventory
  • dmsmanager - DMS configurations
  • alerts - Alert subscriptions
  • va - Validation Authority
  • kms - Key Management Service

Automated Backup Script

#!/bin/bash
# /usr/local/bin/lamassu-backup.sh

set -euo pipefail

# Configuration
BACKUP_DIR="/backup/lamassu"
PG_HOST="localhost"
PG_USER="postgres"
PG_DATABASE="lamassu"
RETENTION_DAYS=30
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p "${BACKUP_DIR}"

# Dump database with compression
echo "Starting backup at $(date)"
pg_dump -h "${PG_HOST}" -U "${PG_USER}" -d "${PG_DATABASE}" \
  --format=custom \
  --compress=9 \
  --file="${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump"

echo "Backup completed: lamassu_${TIMESTAMP}.dump"

# Calculate checksum
sha256sum "${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump" \
  > "${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump.sha256"

# Encrypt backup
gpg --encrypt \
  --recipient backup@yourorg.com \
  --output "${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump.gpg" \
  "${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump"

# Remove unencrypted backup
rm "${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump"

# Upload to remote storage (S3 example)
aws s3 cp "${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump.gpg" \
  "s3://yourorg-lamassu-backups/database/" \
  --sse aws:kms \
  --sse-kms-key-id "arn:aws:kms:us-east-1:123456789:key/your-key-id"

aws s3 cp "${BACKUP_DIR}/lamassu_${TIMESTAMP}.dump.sha256" \
  "s3://yourorg-lamassu-backups/database/"

# Clean up old local backups
find "${BACKUP_DIR}" -name "lamassu_*.dump.gpg" -mtime +${RETENTION_DAYS} -delete
find "${BACKUP_DIR}" -name "lamassu_*.sha256" -mtime +${RETENTION_DAYS} -delete

echo "Backup process completed at $(date)"
Schedule with cron:
# Run backup every hour
0 * * * * /usr/local/bin/lamassu-backup.sh >> /var/log/lamassu-backup.log 2>&1

Point-in-Time Recovery

Enable PostgreSQL Write-Ahead Logging (WAL) archiving for point-in-time recovery:
# postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /backup/wal/%f && cp %p /backup/wal/%f'
archive_timeout = 300  # Archive every 5 minutes
Archive WAL files to S3:
# Archive command for S3
archive_command = 'aws s3 cp %p s3://yourorg-lamassu-backups/wal/%f'

Multi-Schema Backup

If using separate databases (legacy architecture):
#!/bin/bash
# Backup all Lamassu databases

DATABASES=("ca" "devicemanager" "dmsmanager" "alerts" "va" "kms")
BACKUP_DIR="/backup/lamassu"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

for db in "${DATABASES[@]}"; do
  echo "Backing up ${db}..."
  pg_dump -h localhost -U postgres -d "${db}" \
    --format=custom \
    --compress=9 \
    --file="${BACKUP_DIR}/${db}_${TIMESTAMP}.dump"
done

echo "All databases backed up"

Restoring from Backup

Full Database Restore

#!/bin/bash
# Restore Lamassu database from backup

set -euo pipefail

BACKUP_FILE="$1"
PG_HOST="localhost"
PG_USER="postgres"
PG_DATABASE="lamassu"

if [ -z "${BACKUP_FILE}" ]; then
  echo "Usage: $0 <backup_file.dump>"
  exit 1
fi

# Download from S3 if needed
if [[ "${BACKUP_FILE}" == s3://* ]]; then
  echo "Downloading backup from S3..."
  LOCAL_FILE="/tmp/$(basename ${BACKUP_FILE})"
  aws s3 cp "${BACKUP_FILE}" "${LOCAL_FILE}"
  BACKUP_FILE="${LOCAL_FILE}"
fi

# Decrypt if encrypted
if [[ "${BACKUP_FILE}" == *.gpg ]]; then
  echo "Decrypting backup..."
  gpg --decrypt "${BACKUP_FILE}" > "${BACKUP_FILE%.gpg}"
  BACKUP_FILE="${BACKUP_FILE%.gpg}"
fi

# Verify checksum if available
if [ -f "${BACKUP_FILE}.sha256" ]; then
  echo "Verifying backup integrity..."
  sha256sum -c "${BACKUP_FILE}.sha256"
fi

# Stop Lamassu services
echo "Stopping Lamassu services..."
systemctl stop lamassu-ca
systemctl stop lamassu-device-manager
systemctl stop lamassu-dms-manager

# Drop existing database (CAUTION!)
echo "Dropping existing database..."
psql -h "${PG_HOST}" -U "${PG_USER}" -c "DROP DATABASE IF EXISTS ${PG_DATABASE};"

# Recreate database
echo "Creating database..."
psql -h "${PG_HOST}" -U "${PG_USER}" -c "CREATE DATABASE ${PG_DATABASE};"

# Restore from backup
echo "Restoring from backup..."
pg_restore -h "${PG_HOST}" -U "${PG_USER}" -d "${PG_DATABASE}" \
  --verbose \
  "${BACKUP_FILE}"

echo "Database restore completed"

# Restart services
echo "Starting Lamassu services..."
systemctl start lamassu-ca
systemctl start lamassu-device-manager
systemctl start lamassu-dms-manager

echo "Restore process completed successfully"

Point-in-Time Recovery

Restore to a specific point in time using base backup + WAL replay:
#!/bin/bash
# Point-in-time recovery to specific timestamp

BASE_BACKUP="/backup/lamassu/lamassu_20250309_120000.dump"
RECOVERY_TARGET="2025-03-09 14:30:00"

# Restore base backup
pg_restore -d lamassu "${BASE_BACKUP}"

# Configure recovery target
cat > /var/lib/postgresql/recovery.conf <<EOF
restore_command = 'aws s3 cp s3://yourorg-lamassu-backups/wal/%f %p'
recovery_target_time = '${RECOVERY_TARGET}'
recovery_target_action = 'promote'
EOF

# Restart PostgreSQL to begin recovery
systemctl restart postgresql

# Monitor recovery progress
tail -f /var/log/postgresql/postgresql.log

Crypto Engine Backup

HashiCorp Vault Backup

Vault stores CA private keys and must be backed up separately from the database. Backup Vault snapshots:
#!/bin/bash
# Backup HashiCorp Vault

VAULT_ADDR="https://vault.internal:8200"
VAULT_TOKEN="${VAULT_TOKEN}"
BACKUP_DIR="/backup/vault"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Take snapshot (requires Vault Enterprise or Raft storage)
vault operator raft snapshot save \
  "${BACKUP_DIR}/vault_snapshot_${TIMESTAMP}.snap"

# Encrypt snapshot
gpg --encrypt \
  --recipient backup@yourorg.com \
  --output "${BACKUP_DIR}/vault_snapshot_${TIMESTAMP}.snap.gpg" \
  "${BACKUP_DIR}/vault_snapshot_${TIMESTAMP}.snap"

rm "${BACKUP_DIR}/vault_snapshot_${TIMESTAMP}.snap"

# Upload to S3
aws s3 cp "${BACKUP_DIR}/vault_snapshot_${TIMESTAMP}.snap.gpg" \
  "s3://yourorg-lamassu-backups/vault/"
Restore Vault from snapshot:
# Stop Vault
systemctl stop vault

# Download snapshot
aws s3 cp "s3://yourorg-lamassu-backups/vault/vault_snapshot_20250309.snap.gpg" \
  /tmp/vault_snapshot.snap.gpg

# Decrypt
gpg --decrypt /tmp/vault_snapshot.snap.gpg > /tmp/vault_snapshot.snap

# Restore snapshot
vault operator raft snapshot restore /tmp/vault_snapshot.snap

# Start Vault
systemctl start vault
Vault’s auto-unseal feature with cloud KMS ensures Vault can automatically unseal after recovery without manual intervention.

AWS KMS Backup

AWS KMS keys are managed by AWS and automatically replicated. Back up key policies and aliases:
#!/bin/bash
# Backup AWS KMS key metadata

KEY_IDS=$(aws kms list-keys --query 'Keys[*].KeyId' --output text)
BACKUP_DIR="/backup/aws-kms"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

mkdir -p "${BACKUP_DIR}/${TIMESTAMP}"

for key_id in ${KEY_IDS}; do
  # Export key policy
  aws kms get-key-policy --key-id "${key_id}" --policy-name default \
    > "${BACKUP_DIR}/${TIMESTAMP}/${key_id}_policy.json"
  
  # Export key metadata
  aws kms describe-key --key-id "${key_id}" \
    > "${BACKUP_DIR}/${TIMESTAMP}/${key_id}_metadata.json"
  
  # List aliases
  aws kms list-aliases --key-id "${key_id}" \
    > "${BACKUP_DIR}/${TIMESTAMP}/${key_id}_aliases.json"
done

# Archive
tar -czf "${BACKUP_DIR}/kms_backup_${TIMESTAMP}.tar.gz" \
  -C "${BACKUP_DIR}" "${TIMESTAMP}"

PKCS#11 HSM Backup

HSM key backup depends on your HSM vendor: SoftHSM (development):
# Backup SoftHSM token directory
cp -r /var/lib/softhsm/tokens /backup/softhsm/tokens_$(date +%Y%m%d)
Production HSM: Follow vendor-specific procedures:
  • Thales/Gemalto: Use nCipher Security World backup
  • Utimaco: Export key blobs with m-of-n key splitting
  • AWS CloudHSM: Use CloudHSM cluster backups
HSM backup procedures often involve physical security tokens or key custodians. Document and test your HSM backup/restore procedure regularly.

Configuration Backup

Service Configuration Files

#!/bin/bash
# Backup Lamassu configuration

CONFIG_DIRS=(
  "/etc/lamassu"
  "/etc/systemd/system/lamassu-*.service"
  "/usr/local/bin/lamassu-*"
)

BACKUP_DIR="/backup/config"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

tar -czf "${BACKUP_DIR}/lamassu_config_${TIMESTAMP}.tar.gz" \
  "${CONFIG_DIRS[@]}"

# Upload to S3
aws s3 cp "${BACKUP_DIR}/lamassu_config_${TIMESTAMP}.tar.gz" \
  "s3://yourorg-lamassu-backups/config/"

Infrastructure as Code

Store configuration in version control:
# Git repository structure
lamassu-infrastructure/
├── terraform/           # Infrastructure definitions
   ├── vpc.tf
   ├── rds.tf
   └── eks.tf
├── helm/                # Kubernetes manifests
   └── values.yaml
├── ansible/             # Configuration management
   └── playbooks/
└── configs/             # Service configurations
    ├── ca-config.yaml
    └── dms-config.yaml

Disaster Recovery

Recovery Time Objective (RTO)

Target recovery times:
ScenarioRTORPO
Database failure30 minutes1 hour
Vault failure1 hour1 day
Full datacenter loss4 hours1 day
Ransomware/corruption2 hours1 day

Disaster Recovery Runbook

1

Assess Damage

  • Identify affected components (database, services, crypto engines)
  • Determine root cause (hardware failure, data corruption, security incident)
  • Declare incident and activate DR team
2

Provision Infrastructure

  • Launch replacement VMs or containers
  • Restore network configuration
  • Configure DNS to point to DR environment
3

Restore Database

  • Download latest backup from S3
  • Decrypt and verify integrity
  • Restore to PostgreSQL instance
  • Apply WAL files for point-in-time recovery if needed
4

Restore Crypto Engines

  • Restore Vault from snapshot OR
  • Restore HSM keys from secure backup OR
  • Verify AWS KMS keys are accessible
5

Restore Configuration

  • Deploy service configurations from version control
  • Restore TLS certificates
  • Configure environment variables and secrets
6

Start Services

  • Start database
  • Start crypto engines (Vault)
  • Start Lamassu services (CA, Device Manager, DMS Manager)
  • Verify health checks pass
7

Validate Operation

  • Test certificate issuance
  • Test EST enrollment
  • Verify API endpoints respond
  • Check monitoring dashboards
8

Resume Operations

  • Update DNS to production endpoints
  • Notify stakeholders
  • Monitor closely for 24 hours
  • Conduct post-mortem

DR Testing

Regularly test disaster recovery procedures:
#!/bin/bash
# DR test script - Restore to isolated environment

DR_ENV="dr-test"
LATEST_BACKUP=$(aws s3 ls s3://yourorg-lamassu-backups/database/ | \
  sort | tail -n 1 | awk '{print $4}')

echo "Testing DR with backup: ${LATEST_BACKUP}"

# Provision DR infrastructure
terraform apply -var="environment=${DR_ENV}"

# Restore database
aws s3 cp "s3://yourorg-lamassu-backups/database/${LATEST_BACKUP}" \
  /tmp/backup.dump.gpg
gpg --decrypt /tmp/backup.dump.gpg > /tmp/backup.dump
pg_restore -d lamassu_dr /tmp/backup.dump

# Restore Vault
aws s3 cp "s3://yourorg-lamassu-backups/vault/$(date +%Y%m%d)_snapshot.gpg" \
  /tmp/vault.snap.gpg
gpg --decrypt /tmp/vault.snap.gpg > /tmp/vault.snap
vault operator raft snapshot restore /tmp/vault.snap

# Validate
curl -k https://lamassu-dr.example.com/api/ca/v1/health

echo "DR test completed. Results in /var/log/dr-test-${DR_ENV}.log"
Conduct DR drills quarterly.

Backup Monitoring

Backup Success Tracking

Monitor backup job completion:
# Check last successful backup
LAST_BACKUP=$(aws s3 ls s3://yourorg-lamassu-backups/database/ | \
  sort | tail -n 1 | awk '{print $4}')

LAST_BACKUP_DATE=$(echo ${LAST_BACKUP} | grep -oP '\d{8}_\d{6}')
LAST_BACKUP_EPOCH=$(date -d "${LAST_BACKUP_DATE:0:8} ${LAST_BACKUP_DATE:9:2}:${LAST_BACKUP_DATE:11:2}:${LAST_BACKUP_DATE:13:2}" +%s)
NOW_EPOCH=$(date +%s)

HOURS_SINCE=$(( (NOW_EPOCH - LAST_BACKUP_EPOCH) / 3600 ))

if [ ${HOURS_SINCE} -gt 2 ]; then
  echo "CRITICAL: Last backup was ${HOURS_SINCE} hours ago"
  exit 2
fi

echo "OK: Last backup ${HOURS_SINCE} hours ago"

Backup Integrity Validation

#!/bin/bash
# Validate backup integrity weekly

LATEST_BACKUP=$(aws s3 ls s3://yourorg-lamassu-backups/database/ | \
  sort | tail -n 1 | awk '{print $4}')

# Download backup and checksum
aws s3 cp "s3://yourorg-lamassu-backups/database/${LATEST_BACKUP}" /tmp/
aws s3 cp "s3://yourorg-lamassu-backups/database/${LATEST_BACKUP%.gpg}.sha256" /tmp/

# Verify checksum
cd /tmp
sha256sum -c "${LATEST_BACKUP%.gpg}.sha256"

if [ $? -eq 0 ]; then
  echo "Backup integrity verified"
  # Test restore to temporary database
  gpg --decrypt "/tmp/${LATEST_BACKUP}" > /tmp/test.dump
  createdb test_restore
  pg_restore -d test_restore /tmp/test.dump
  
  if [ $? -eq 0 ]; then
    echo "Backup restore test successful"
  else
    echo "CRITICAL: Backup restore test failed"
    exit 2
  fi
  
  dropdb test_restore
else
  echo "CRITICAL: Backup checksum verification failed"
  exit 2
fi