1# ============================================================================= 2# AI Software Factory — least-privilege IAM policy for the BACKUP identity 3# (TASK-0135 deliverable: "wal-g least-priv IAM policy (put/get on backup 4# prefix only) as a separate manifest"). 5# 6# ⚠ NOT a Kubernetes object — do NOT add this file to kustomization.yaml 7# resources. It is the IAM policy document to attach to the backup 8# identity (AWS IAM user/role, or the MinIO/IAM-equivalent service 9# account) that the postgres backup CronJob + archive_command + the 10# OpenSearch snapshot CronJob use (factory-secrets S3_ACCESS_KEY / 11# S3_SECRET_KEY). 12# 13# Design (least privilege — the backup identity can ONLY read/write the 14# backup bucket, only the backup prefixes, and only the verbs the backup 15# flow needs): 16# - The app identity (factory-files / factory-thumbs) is a DIFFERENT 17# identity with its own policy (see the files bucket setup, TASK-0101); 18# the backup identity has NO access to the app buckets and vice versa. 19# - Base backups: wal-g needs PutObject (upload) + GetObject/ListBucket 20# (backup-fetch / wal-fetch at restore time + the backup-health 21# ListObjectsV2) on `pg/basebackups_005/` and `pg/wal_005/`. 22# - OpenSearch S3 repository: needs PutObject + GetObject + 23# ListMultipartUpload/AbortMultipartUpload (snapshot/restore use 24# multipart) on `opensearch/`. 25# - GetBucketVersioning is allowed (read-only) so the runbook §8.6 26# verification step (`mc admin bucket info` / `aws s3api 27# get-bucket-versioning`) can run as the backup identity without 28# elevating privileges. 29# 30# ARN placeholders: replace `arn:aws:iam::111122223333` (account) and 31# `factory-backups` (bucket) for your deployment. For MinIO/self-hosted 32# S3, create a service account scoped to the `factory-backups` bucket 33# (e.g. `mc admin user add` + a policy with the same statement shape). 34# ============================================================================= 35PolicyDocument: 36 Version: "2012-10-17" 37 Statement: 38 - Sid: BackupReadWritePgPrefix 39 Effect: Allow 40 Action: 41 - s3:PutObject 42 - s3:GetObject 43 - s3:DeleteObject # only needed for the manual `wal-g delete` 44 # retention operation (runbook §8.6); remove 45 # if retention is done by another identity 46 Resource: 47 - "arn:aws:s3:::factory-backups/pg/basebackups_005/*" 48 - "arn:aws:s3:::factory-backups/pg/wal_005/*" 49 - Sid: BackupListPgPrefix 50 Effect: Allow 51 Action: 52 - s3:ListBucket # ListObjectsV2 with prefix=pg/… (health 53 # gate + wal-g backup-list) 54 Resource: 55 - "arn:aws:s3:::factory-backups" 56 Condition: 57 StringLike: 58 s3:Prefix: 59 - "pg/basebackups_005/*" 60 - "pg/wal_005/*" 61 - Sid: BackupReadWriteOsSnapshots 62 Effect: Allow 63 Action: 64 - s3:PutObject 65 - s3:GetObject 66 - s3:DeleteObject 67 - s3:ListMultipartUploads 68 - s3:AbortMultipartUpload # OpenSearch S3 repo snapshot/restore 69 # (multipart uploads) 70 Resource: 71 - "arn:aws:s3:::factory-backups/opensearch/*" 72 - Sid: BackupListOsSnapshots 73 Effect: Allow 74 Action: 75 - s3:ListBucket 76 Resource: 77 - "arn:aws:s3:::factory-backups" 78 Condition: 79 StringLike: 80 s3:Prefix: 81 - "opensearch/*" 82 - Sid: BackupReadVersioning 83 Effect: Allow 84 Action: 85 - s3:GetBucketVersioning 86 Resource: 87 - "arn:aws:s3:::factory-backups" 88