S3 Bucket Policy with example on preventing deletion of objects by a user account

Bucket policies are JSON documents that are used to grant access to S3 resources,i.e. to objects inside an S3 bucket.Bucket policies are assigned by the bucket owner.

Format/Structure of S3 bucket policy document:

{
    "Version": "2012-10-17",
    "Id": "Policy34545544",
    "Statement": [
        {
            "Sid": "Stmt648374833",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::sample-bucket",
                "arn:aws:s3:::sample-bucket/*"
            ],
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "IP_ADRESS"
                }
            }
        }
    ]
}
 

Version-A version template.Currently 2012-10-17 has been in use until AWS updates it.

Id-Identifier for the policy document

Statement-An array of statements .Individual statements specify the effects on the S3 resources as you specify.A statement comprises of Sid,Effect,Principal,Action,Resource,Condition

Sid-are unique identifiers of the statements

Effect-is either Allow or Deny depending on our target goal

Principal-the user,account or entity which we are Allowing or Denying action on the resource

Action-Specific S3 activity e.g. DeleteObject, PutObject

Resource-the bucket or objects in the bucket we are restricting access or allowing access to.This is in ARN form.

Condition-condition specifying when the policy applies.

Example- s3 bucket policy example

We have two accounts  named devsoughttestuser001 and devsoughttestuser002.They are non root  sub accounts with S3FullAccess policy attached to them to perform S3 operations.

User devsoughttestuser001 creates a bucket named devsought-bucket-1 with a folder named folder-1/ and applies below policy.

{
    "Version": "2012-10-17",
    "Id": "Policy6584658374834",
    "Statement": [
        {
            "Sid": "Stmt5438363827363",
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam:: 437363836383:user/devsoughttestuser002"
            },
            "Action": "s3:DeleteObject",
            "Resource": "arn:aws:s3:::devsought-bucket-1/*"
        }
    ]
}

Explanation:

The above policy denies user with name  devsoughttestuser002 the capability to delete objects from bucket devsought-bucket-1 .If they try ,they get the error as below.

However,they can perform other bucket operations like uploading objects into the bucket(PutObject).

Tip-Common error when writing bucket policies targeting objects

Most times,we want to Allow/Deny operations targeting object operations e.g. PutObject, DeleteObject but we specify the Resource as a  bucket without the ‘/*’ e.g. "Resource": "arn:aws:s3:::devsought-bucket-1",in this instance,the policy creation will Fail with Error ‘Action does not apply to any resource(s) in statement’ as shown below.

Explanation:Since we are targeting object specific actions ,i.e.actions with Object (PutObject,DeleteObject),we need to append /* to the Resource ARN .For bucket specific actions e.g. ListBucket,the Resource ARN should not have the /* as these are meant to be applied to the bucket and not objects.

About the Author - John Kyalo Mbindyo(Bsc Computer Science) is a Senior Application Developer currently working at NCBA Bank Group,Nairobi- Kenya.He is passionate about making programming tutorials and sharing his knowledge with other software engineers across the globe. You can learn more about him and follow him on  Github.