- Recipes
- Anonymous GET access
- Anonymous GET access - match HTTP referrer
- Full access for specific IAM user/role
- GET/PUT/DELETE access to specific path within a bucket
- Restricted LIST & PUT/DELETE access to specific path within a bucket
- Full access (and S3 console) for specific IAM users
- Bucket and object delete deny
- Bucket enforce SSL requests only
- CloudTrail log receive
- CloudFront origin access control (OAC) GET access
- Reference
Type: bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
Type: bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
],
"Condition": {
"StringLike": {
"aws:Referer": [
"http://domain.com/*",
"http://www.domain.com/*"
]
}
}
}
]
}
Type: bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::ACCOUNT_ID:user/USERNAME_A",
"arn:aws:iam::ACCOUNT_ID:user/USERNAME_B",
"arn:aws:iam::ACCOUNT_ID:user/USERNAME_C",
"arn:aws:iam::ACCOUNT_ID:role/ROLE_A",
"arn:aws:iam::ACCOUNT_ID:role/ROLE_B",
"arn:aws:iam::ACCOUNT_ID:role/ROLE_C"
]
},
"Resource": [
"arn:aws:s3:::BUCKET_NAME",
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
Type: user/group/role
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::BUCKET_NAME"
]
},
{
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::BUCKET_NAME/BUCKET_PATH/*"
]
}
]
}
Note: The s3:ListBucket
action against the bucket as a whole allows for the listing of bucket objects.
Type: user/group/role
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::BUCKET_NAME"
],
"Condition": {
"StringEquals": {
"s3:delimiter": ["/"],
"s3:prefix": ["","BUCKET_PATH/"]
}
}
},
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::BUCKET_NAME"
],
"Condition": {
"StringLike": {
"s3:prefix": ["BUCKET_PATH/BUCKET_SUB_PATH/*"]
}
}
},
{
"Action": [
"s3:DeleteObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::BUCKET_NAME/BUCKET_PATH/BUCKET_SUB_PATH/*"
]
}
]
}
Note: This policy effectively provides protected user folders within an S3 bucket:
- The first
s3:ListBucket
action allows listing only of objects at the bucket root and underBUCKET_PATH/
. - The second
s3:ListBucket
action allows listing of objects from the path ofBUCKET_PATH/BUCKET_SUB_PATH/
and below. - Technique is covered here under the heading Block 2: Allow listing objects in root and home folders.
Type: user/group/role
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:ListAllMyBuckets",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
Type: bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:DeleteBucket",
"Effect": "Deny",
"Principal": "*",
"Resource": [
"arn:aws:s3:::BUCKET_NAME"
]
},
{
"Action": "s3:DeleteObject",
"Effect": "Deny",
"Principal": "*",
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
Type: bucket
See: https://repost.aws/knowledge-center/s3-bucket-policy-for-config-rule
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:*",
"Effect": "Deny",
"Principal": "*",
"Resource": [
"arn:aws:s3:::BUCKET_NAME/",
"arn:aws:s3:::BUCKET_NAME/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
Type: bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetBucketAcl",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
],
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudtrail:AWS_REGION:AWS_ACCOUNT_ID:trail/TRAIL_NAME"
}
}
},
{
"Action": "s3:PutObject",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Resource": [
"arn:aws:s3:::BUCKET_NAME/AWSLogs/AWS_ACCOUNT_ID/*"
],
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudtrail:AWS_REGION:AWS_ACCOUNT_ID:trail/TRAIL_NAME",
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
Type: bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetObject",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
],
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudfront::AWS_ACCOUNT_ID:distribution/DISTRIBUTION_ID"
}
}
}
]
}
- Writing IAM Policies: How to Grant Access to an Amazon S3 Bucket
- Writing IAM Policies: Grant Access to User-Specific Folders in an Amazon S3 Bucket
- Summary of
Action
types and their use:- https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html
- Grouped by bucket vs. object action types, which is very handy.
- Amazon S3 condition key examples
- Example IAM identity-based policies
Nice one @gheorghina - i've had major pains with bucket -> bucket copies in the past.
The best advice I can give, always copy from a user/role in the target bucket account that can reach into the source. That way, you don't have to worry about getting ACL's correct on the new objects as they are placed into the target bucket.
I've had a few instances where I've not done this, and then the target bucket objects can't actually be read by account itself!