Deny object deletes in a bucket policy
When a bucket policy contains statements, a matching Deny wins over a matching Allow for the same principal, action, and resource. Use a deny when an allow would otherwise permit a destructive action.
The service account must already exist in the organisation that owns the bucket. See Bucket policies.
Policy
AllowServiceAccountWrite allows list, get, put, and delete. DenyDeletes matches the same service account for s3:DeleteObject and s3:DeleteObjectVersion on objects in the bucket. The deny wins for those two actions, so the service account can list, read, and upload, and delete calls are denied.
Replace org-identity, sa-identity, and my-bucket.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowServiceAccountWrite",
"Effect": "Allow",
"Principal": {
"Thalassa": "arn:thalassa:iam:::serviceaccount/org-identity:sa-identity"
},
"Action": ["s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": [
"arn:thalassa:s3:::my-bucket",
"arn:thalassa:s3:::my-bucket/*"
]
},
{
"Sid": "DenyDeletes",
"Effect": "Deny",
"Principal": {
"Thalassa": "arn:thalassa:iam:::serviceaccount/org-identity:sa-identity"
},
"Action": ["s3:DeleteObject", "s3:DeleteObjectVersion"],
"Resource": ["arn:thalassa:s3:::my-bucket/*"]
}
]
}s3:DeleteObject appears in both statements. For that action the deny overrides the allow. s3:DeleteObjectVersion is named only on the deny, so a later allow for that action on the same principal and object ARN is still overridden by DenyDeletes.
Attach the policy
Set the document as the bucket’s policy field when you create or update the bucket, or paste it into the console bucket policy JSON editor.
Upload an object with the service account, then delete it. The upload is allowed by AllowServiceAccountWrite. The delete matches DenyDeletes and is denied.