Skip to content

epomatti/aws-s3-permissions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 

Repository files navigation

AWS S3 Permissions & ACL

This exercise will demonstrate different behaviors for S3 permissions, which include:

  • Bucket policies
  • Bucket ACLs
  • IAM Policies

When BucketOwnerEnforced is set (which is the default), ACLs are disabled and permissions must be set with policies.

Setup

Create the sample bucket:

# Setup the common variables
region='us-east-2'
bucket="bucket-pomatti-permissions"
file='confidential.csv'

# Create the bucket
aws s3api create-bucket --bucket $bucket --region $region \
  --create-bucket-configuration "LocationConstraint=$region"

For new S3 buckets, the feature Block all public access is enabled by default.

Additionally, as per ACL overview:

By default, Object Ownership is set to the bucket owner enforced setting, and all ACLs are disabled. When ACLs are disabled, the bucket owner owns all the objects in the bucket and manages access to them exclusively by using access-management policies.

Now upload the file to the bucket:

aws s3api put-object --bucket $bucket --key $file --body $file

Make sure to check the bucket ACL at the start:

aws s3api get-bucket-acl --bucket $bucket

ACL exercise

Trying to PUT a public ACL to an object will fail because ACLs are disabled.

aws s3api put-object-acl --bucket $bucket --key $file --acl public-read

First, enable the bucket ACLs by setting the ownership to BucketOwnerPreferred:

aws s3api put-bucket-ownership-controls \
    --bucket $bucket \
    --ownership-controls="Rules=[{ObjectOwnership=BucketOwnerPreferred}]"

Now, disable the public ACL block by setting BlockPublicAcls=false and try again:

aws s3api put-public-access-block \
  --bucket $bucket \
  --public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

# This should work now
aws s3api put-object-acl --bucket $bucket --key $file --acl public-read

This command will succeed. However, it would still not be possible to download the file publicly (anonymously). For that, configuration IgnorePublicAcls=false needs to be set:

aws s3api put-public-access-block \
  --bucket $bucket \
  --public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=true,RestrictPublicBuckets=true"

Now an interesting use case can be applied.

By blocking NEW ACLs with BlockPublicAcls=true, access to the existing ACLs is maintained:

aws s3api put-public-access-block \
  --bucket $bucket \
  --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=false,BlockPublicPolicy=true,RestrictPublicBuckets=true"

To block everything again, both new and existing ACLs need to be blocked/ignored with BlockPublicAcls=true,IgnorePublicAcls=true:

aws s3api put-public-access-block \
  --bucket $bucket \
  --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

Before moving on let's remove the object public ACL:

aws s3api put-object-acl --bucket $bucket --key $file --acl private

Bucket Policies

Adding a bucket policy at this stage will fail:

aws s3api put-bucket-policy --bucket $bucket --policy file://bucket-policy.json

To allow it, set BlockPublicPolicy=false:

aws s3api put-public-access-block \
  --bucket $bucket \
  --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=false,RestrictPublicBuckets=true"

Now creating a new bucket policy should work:

aws s3api put-bucket-policy --bucket $bucket --policy file://bucket-policy.json

Clean-up

aws s3 rb s3://$bucket --force

Releases

No releases published

Packages

No packages published