diff --git a/.env.production.example b/.env.production.example index ee3d19cf4..4a56a53b6 100644 --- a/.env.production.example +++ b/.env.production.example @@ -306,6 +306,20 @@ API_TOKEN_HMAC_KEY="" # BACKUP_S3_SECRET_KEY="" # BACKUP_ENCRYPTION_KEY="" +# The two optional members of the set, both with defaults, so leaving them +# unset does not disable backups. +# +# Region sent with the SigV4 signature. Default "auto", which is what +# Cloudflare R2 expects; AWS S3 and most MinIO deployments want their real +# region name here. +# BACKUP_S3_REGION="auto" +# +# How long backup objects are meant to live, in days. Default 30, minimum 1. +# The worker never deletes an object -- its grant is PutObject, GetObject and +# AbortMultipartUpload -- so this number is what you set the bucket's own +# lifecycle rule to. See docs/ops/backup-restore.md. +# BACKUP_RETENTION_DAYS="30" + # ----------------------------------------------------------------------------- # Audit-trail retention -- optional diff --git a/docs/ops/backup-restore.md b/docs/ops/backup-restore.md index 92991852b..0ac2d7ad5 100644 --- a/docs/ops/backup-restore.md +++ b/docs/ops/backup-restore.md @@ -54,8 +54,10 @@ Cloudflare R2 the **Object Read & Write** token already covers all three. ## Bucket lifecycle (recommended) -The worker prunes objects older than `BACKUP_RETENTION_DAYS`, but the -storage provider's lifecycle rule is the canonical safety net: +The worker never deletes a backup object: its grant covers PutObject, +GetObject and AbortMultipartUpload only, so a compromised worker cannot +wipe the history. Expiry is the storage provider's lifecycle rule, set to +match `BACKUP_RETENTION_DAYS`: ``` Filter: "" (all objects)