Backup System
Keshless uses an automated backup system powered by GCP Cloud Scheduler to ensure data integrity and enable disaster recovery.
Backup Schedule
| Job | Schedule | Time (UTC) | Description |
|---|---|---|---|
| PostgreSQL Daily | 0 2 * * * | Daily 2:00 AM | Full database export |
| PostgreSQL Monthly | 0 2 1 * * | 1st of month 2:00 AM | Long-term retention backup |
| Secrets Backup | 0 4 * * 0 | Sundays 4:00 AM | Encrypted config backup |
| Cleanup | 0 5 * * 1 | Mondays 5:00 AM | Remove expired backups |
PostgreSQL Backups
What's Backed Up
The full PostgreSQL database is exported as a compressed SQL dump file.
Critical Tables:
| Category | Tables |
|---|---|
| Users | users, vendors, vendorsubusers, wallets |
| Transactions | wallettransactions, transactions |
| Accounting | journalentries, ledgerentries, accountbalances |
| Compliance | alerts, customerriskprofiles, sars |
| Configuration | nfccards, feeconfigs, transactionlimitconfigs |
| Audit | auditlog (hash-chained for integrity) |
Storage Structure
All backups are stored in GCP Cloud Storage (europe-west1):
| Path | Contents |
|---|---|
gs://keshless-backups/postgresql/daily/{date}/ | Daily backup + manifest |
gs://keshless-backups/postgresql/monthly/{month}/ | Monthly backup + manifest |
Manifest File
Each backup includes a manifest.json with metadata:
| Field | Description |
|---|---|
| backupType | daily or monthly |
| timestamp | Backup creation time |
| database | Database name |
| filename | Backup file name |
| sizeBytes | Uncompressed size |
| compressedBytes | Compressed size |
| durationMs | Backup duration |
| tables | Array of table row counts |
Document Storage
GCP Cloud Storage Structure
| Bucket | Folder | Contents |
|---|---|---|
keshless-documents | kyc/ | KYC documents (ID cards) |
keshless-documents | selfies/ | User selfies |
keshless-documents | vendor-kyc/ | Vendor verification docs |
keshless-documents | vendor-media/ | Vendor logos/media |
Security
| Feature | Description |
|---|---|
| Private buckets | No public access (--public-access-prevention) |
| Signed URLs | Time-limited access (15-minute expiry for KYC) |
| Encryption at rest | AES-256 (Google-managed keys) |
| Audit logging | All document access is logged |
Secrets Backup
What's Backed Up
| Category | Contents |
|---|---|
| Cloud Run Env Vars | All env vars from keshless-api service |
| Sensitive Variables | DATABASE_URL, JWT_SECRET, JWT_REFRESH_SECRET, API keys |
Encryption
| Property | Value |
|---|---|
| Algorithm | AES-256-GCM |
| Key Derivation | SHA-256 hash of SECRETS_ENCRYPTION_KEY |
| IV | Random 16-byte per backup |
| Integrity | Auth tag verification |
CRITICAL: Store SECRETS_ENCRYPTION_KEY in a password manager. Without it, backups cannot be decrypted.
Storage Location
| Path | Contents |
|---|---|
gs://keshless-backups/secrets/weekly/{date}.json.encrypted | Weekly encrypted backup |
gs://keshless-backups/secrets/latest.json.encrypted | Most recent backup |
Retention Policy
| Backup Type | Retention Period |
|---|---|
| PostgreSQL Daily | 2 years (730 days) |
| PostgreSQL Monthly | 5 years (1825 days) |
| Secrets Weekly | 2 years (730 days) |
The cleanup job runs weekly to remove expired backups.
Cloud Scheduler Jobs
Job Configuration
| Job Name | URI Path | Schedule |
|---|---|---|
keshless-backup-postgres-daily-{env} | /backup-jobs/postgres | 0 2 * * * |
keshless-backup-postgres-monthly-{env} | /backup-jobs/postgres-monthly | 0 2 1 * * |
keshless-backup-secrets-weekly-{env} | /backup-jobs/secrets | 0 4 * * 0 |
keshless-backup-cleanup-weekly-{env} | /backup-jobs/cleanup | 0 5 * * 1 |
Required Headers
| Header | Value |
|---|---|
X-Job-Secret | Environment-specific job secret |
Content-Type | application/json |
API Endpoints
| Environment | Base URL |
|---|---|
| Production | https://api.keshless.app |
| Development | https://keshless-api-dev-659214682765.europe-west1.run.app |
Manual Testing
Test backup endpoints with:
bash
curl -X POST \
-H "X-Job-Secret: your-job-secret" \
-H "Content-Type: application/json" \
https://{api-url}/backup-jobs/{job-name}| Job Name | Description |
|---|---|
postgres | Daily PostgreSQL backup |
postgres-monthly | Monthly PostgreSQL backup |
secrets | Secrets backup |
cleanup | Old backup cleanup |
Monitoring
Verification Steps
| Step | Method |
|---|---|
| View job history | Cloud Scheduler > Jobs > View Logs |
| Check backup files | Cloud Storage > keshless-backups bucket |
| List via CLI | gcloud storage ls gs://keshless-backups/postgresql/daily/ |
| Check total size | gcloud storage du gs://keshless-backups/ --summarize |
Recommended Alerts
| Alert | Condition |
|---|---|
| Job failures | Any job execution failure |
| Missing backups | No new files for 2+ days |
| Unusual sizes | Significant deviation from normal |