Skip to content

fix: the nightly database backup only uploads into a bucket owned by the S3 keys' account - #711

Merged
lukepolo merged 3 commits into
mainfrom
fix/backup-bucket-owner
Nov 1, 2026
Merged

lukepolo merged 3 commits into
mainfrom
fix/backup-bucket-owner

Conversation

@lukepolo

@lukepolo lukepolo commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Hardens the nightly database backup so it only uploads to a remote bucket that belongs to the account the panel's S3 keys are in.

  • Before uploading to a remote endpoint, the backup lists the account's buckets. If the configured bucket isn't there, it stops without uploading, prints how to fix it, and the CronJob shows as failed.
  • On AWS (*.amazonaws.com and *.amazonaws.com.cn, ignoring case, scheme and trailing slash), it runs s3api head-bucket --expected-bucket-owner with the keys' 12-digit account id from STS and stops if that fails. The prune's list-objects-v2 and delete-object pass the same owner. aws s3 cp doesn't take the option, so the upload itself runs without it and still handles multipart.
  • Keys that can't list buckets (AccessDenied, 401 or 403, e.g. bucket-scoped keys) still upload as before. Off AWS they print a one-line note that the owner couldn't be checked.
  • Any other listing error fails the job the same way an upload error does. The in-cluster rustfs/minio store, the zip and the keep-7 prune are unchanged, except that the prune now deletes with s3api delete-object.
  • tests/scripts/postgres_backup_test.sh runs the CronJob's script against stubbed aws/pg_dump/zip. The stub rejects options the real CLI rejects. The test is wired into the panel-scripts workflow (including base/backups/**).

…the S3 keys' account

For a remote S3 endpoint the backup now lists the account's buckets first and
refuses to upload when the configured bucket is not among them. On AWS every
call also passes --expected-bucket-owner with the account id from STS. Keys
that cannot list buckets still upload, with a note. The in-cluster store is
unchanged.
…akes --expected-bucket-owner where aws s3 cp and rm do not

aws s3 cp and aws s3 rm reject --expected-bucket-owner, so every AWS backup
failed. On AWS the owner is now checked with s3api head-bucket before the
upload, s3 cp runs without the option and keeps multipart, and the prune
lists and deletes through s3api with the owner. The AWS endpoint match
ignores case, a scheme and a trailing slash, and covers amazonaws.com.cn.
A 401 on the bucket listing counts as keys that cannot list buckets.
@lukepolo
lukepolo merged commit b3077ab into main Nov 1, 2026
1 check passed
@lukepolo
lukepolo deleted the fix/backup-bucket-owner branch November 1, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant