// Automated backup service (runs daily at 02:00 UTC)asyncfunctionperformVaultBackup():Promise<void>{consttimestamp=newDate().toISOString().replace(/[:.]/g,'-');constbackupDate=newDate().toISOString().split('T')[0];constisMonthly=newDate().getDate()===1;try{// Take Vault snapshotconsole.log(`[${timestamp}] Starting Vault backup...`);constsnapshot=awaitvaultClient.sys.snapshot();// Encrypt snapshot with AES-256-GCMconstencryptedSnapshot=awaitencryptBackup(snapshot,backupEncryptionKey);// Generate checksum for integrity verificationconstchecksum=crypto.createHash('sha256').update(encryptedSnapshot).digest('hex');// Determine backup path (daily or monthly)constbackupPath=isMonthly?`monthly/${backupDate}/vault-snapshot-${timestamp}.enc`:`daily/${backupDate}/vault-snapshot-${timestamp}.enc`;// Upload to S3awaits3.putObject({Bucket:'penguinmails-vault-backups',Key:backupPath,Body:encryptedSnapshot,Metadata:{checksum:checksum,timestamp:timestamp,vault_version:awaitvaultClient.sys.health().version}});// Verify upload integrityconstuploadedObject=awaits3.headObject({Bucket:'penguinmails-vault-backups',Key:backupPath});if(uploadedObject.Metadata.checksum!==checksum){thrownewError('Backup checksum mismatch after upload');}// Delete local snapshot fileawaitfs.unlink(`/tmp/vault-snapshot-${timestamp}`);// Log backup successawaitauditLog.create({event:'vault_backup_completed',timestamp:newDate().toISOString(),details:{backup_path:backupPath,checksum:checksum,size_bytes:encryptedSnapshot.length,backup_type:isMonthly?'monthly':'daily'}});// Send success notificationawaitsendNotification({type:'vault_backup_success',message:`Vault backup completed successfully: ${backupPath}`,timestamp:timestamp});console.log(`[${timestamp}] Vault backup completed: ${backupPath}`);}catch(error){// Log backup failureawaitauditLog.create({event:'vault_backup_failed',timestamp:newDate().toISOString(),severity:'critical',details:{error:error.message,stack:error.stack}});// Alert admins immediatelyawaitsendAlert({type:'vault_backup_failure',severity:'critical',message:`Vault backup failed: ${error.message}`,timestamp:timestamp});throwerror;}}// Encrypt backup with AES-256-GCMasyncfunctionencryptBackup(snapshot:Buffer,encryptionKey:Buffer):Promise<Buffer>{// Generate random IVconstiv=crypto.randomBytes(16);// Create cipherconstcipher=crypto.createCipheriv('aes-256-gcm',encryptionKey,iv);// Encrypt snapshotconstencrypted=Buffer.concat([cipher.update(snapshot),cipher.final()]);// Get authentication tagconstauthTag=cipher.getAuthTag();// Return: IV + authTag + encrypted datareturnBuffer.concat([iv,authTag,encrypted]);}
Backup Retention Policy
// Clean up old backups (runs daily after backup)asyncfunctioncleanupOldBackups():Promise<void>{constnow=newDate();// Clean up daily backups older than 30 daysconstdailyBackups=awaits3.listObjectsV2({Bucket:'penguinmails-vault-backups',Prefix:'daily/'});for(constbackupofdailyBackups.Contents){constbackupDate=newDate(backup.LastModified);constageInDays=(now.getTime()-backupDate.getTime())/(1000*60*60*24);if(ageInDays>30){awaits3.deleteObject({Bucket:'penguinmails-vault-backups',Key:backup.Key});console.log(`Deleted old daily backup: ${backup.Key}`);}}// Clean up monthly backups older than 12 monthsconstmonthlyBackups=awaits3.listObjectsV2({Bucket:'penguinmails-vault-backups',Prefix:'monthly/'});for(constbackupofmonthlyBackups.Contents){constbackupDate=newDate(backup.LastModified);constageInMonths=(now.getTime()-backupDate.getTime())/(1000*60*60*24*30);if(ageInMonths>12){awaits3.deleteObject({Bucket:'penguinmails-vault-backups',Key:backup.Key});console.log(`Deleted old monthly backup: ${backup.Key}`);}}}
Backup Verification
// Test backup restoration to staging environment (runs weekly)asyncfunctiontestBackupRestoration():Promise<void>{try{// Get latest daily backupconstlatestBackup=awaitgetLatestBackup('daily');// Download encrypted backupconstencryptedBackup=awaits3.getObject({Bucket:'penguinmails-vault-backups',Key:latestBackup.Key});// Decrypt backupconstdecryptedBackup=awaitdecryptBackup(encryptedBackup.Body,backupEncryptionKey);// Restore to staging Vault instanceawaitstagingVaultClient.sys.restore(decryptedBackup);// Verify secrets are accessibleconsttestTenantId='test-tenant-id';consttestSecret=awaitstagingVaultClient.read(`smtp/${testTenantId}/admin`);if(!testSecret){thrownewError('Test secret not found after restoration');}// Log successful testawaitauditLog.create({event:'vault_backup_test_success',timestamp:newDate().toISOString(),details:{backup_tested:latestBackup.Key,staging_vault:'vault-staging.penguinmails.com'}});console.log('Backup restoration test successful');}catch(error){// Alert admins of test failureawaitsendAlert({type:'vault_backup_test_failure',severity:'high',message:`Backup restoration test failed: ${error.message}`});throwerror;}}