Securing S3 Buckets and Objects using Policies

Most of you have been using S3 for various purpose and have been already implemented security policies for the relevant objects and buckets either via API, AWS Console or via using S3 SDK.

In this blog i will be explaining

– Basics on how we can use Resource based policy.

– Basics on how we can use user based policy.

– Policy Examples.

S3 is purely an object based storage which is provided as a service. By default all objects stored in S3 are private when you first upload it. Later using access policies, object owner or bucket owner provide relevant access.

Following are one liner description on S3 components:

  • Object :  File copied or uploaded in S3 bucket.
  • Bucket :  Primary container where all objects are stored.
  • Permission: Where you can assign resource or bucket or user based policy.
  • Life Cycle Policy : Policy defined to automatically move object from one storage class to other.
  • Inventory : Provides you with list of objects their storage class and relevant bucket with encryption information in .csv format.
  • Versioning : Once enabled, s3 objects will be added version based on edit or delete.
  • Encryption: Assign client side or server side encryption on objects and buckets.

Our focus in this blog is on Buckets and Objects and how to control the access.

Controlling Access to S3 can be written based on

  • Resource based policies (Access Control List)
  • User based policies. (Bucket Policy & IAM Policy)

What is Resource?

-An object or bucket

What is Resource Based Policy?

– Policy which is written on Object or on Bucket level. Generally called Access Control List (ACL).

Who is a User?

– Can be AWS account owner.

– Can be IAM user in same AWS account or different AWS account.

– Can be bucket owner.

– Can be object owner.

What is User Based Policy?

-Policy written same as you define IAM policy to the users is called user based policy.

Lets deep dive on both the policies and their structure.

Access Control List (Resource Based)

Reference and more information: https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-access-control.html

Type: XMl based and SDK available for Java, .NET, RestAPI

Components of Policy:

Who Is a Grantee?

                       A grantee can be an AWS account or one of the predefined Amazon S3 groups. You grant permission to an AWS account using the email address or the canonical user ID. However, if you provide an email address in your grant request, Amazon S3 finds the canonical user ID for that account and adds it to the ACL. The resulting ACLs always contain the canonical user ID for the AWS account, not the AWS account’s email address.

Following example give Full Control to the user you define over the bucket or specific object you define.

<?xml version=”1.0″ encoding=”UTF-8″?>
<AccessControlPolicy xmlns=”http://s3.amazonaws.com/doc/2006-03-01/”> #Bucket and Object information
<Owner>
<ID>*** Owner-Canonical-User-ID ***</ID> #AWS account Canonical ID
<DisplayName>owner-display-name</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:type=”Canonical User”>
<ID>*** Owner-Canonical-User-ID ***</ID>
<DisplayName>display-name</DisplayName>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>

Instead of providing a specific Grantee, admins can mention predefined S3 groups as a generic approach. Following are the predefined groups which can be used instead of canonical user

Amazon S3 Predefined Groups

-Authenticated Users group –  http://acs.amazonaws.com/groups/global/AuthenticatedUsers

-All Users group – http://acs.amazonaws.com/groups/global/AllUsers

-Log Delivery group – http://acs.amazonaws.com/groups/s3/LogDelivery

Below mentioned are permission set which can be used instead of FULL CONTROL permission in above policy.

Permission When granted on bucket When granted on object
READ Allows grantee to list the objects in the bucket

s3:ListBucket, s3:ListBucketVersions,                            s3:ListBucketMultipartUploads

Allows grantee to read the object data and its metadata

s3:GetObject,

s3:GetObjectVersion,

 

WRITE Allows grantee to create, overwrite,and delete any object in the bucket

s3:PutObject and s3:DeleteObject.

 

Not applicable
READ_ACP Allows grantee to read the bucket ACL

s3:GetBucketAcl

Allows grantee to read the object ACL

s3:GetObjectAcl and s3:GetObjectVersionAcl

WRITE_ACP Allows grantee to write the ACL for the applicable bucket

s3:PutBucketAcl

Allows grantee to write the ACL for the applicable object

s3:PutObjectAcl and s3:PutObjectVersionAcl

FULL_CONTROL Allows grantee the READ, WRITE, READ_ACP, and WRITE_ACP permissions on the bucket.

Equivalent to granting READ, WRITE, READ_ACP, and WRITE_ACP ACL permissions.

Allows grantee the READ, READ_ACP, and WRITE_ACP permissions on  the objects

How to assign ACL using console?

Note : You can only able to edit the access permission of the following from Console.

  • Admin (Owner) account
  • Add or delete user and edit permission of another AWS Account.
  • Make Bucket or Object public.
  • Edit permission of Log Delivery Group.

-Sign in to AWS console and navigate to S3 service.

-Create a new Bucket

This is the first place where you can define ACL policy

Secondly you can assign ACL policy after creating the bucket.

This are the only option you can get to configure using console

Bucket Policy & User Policy

Type: JSON

Components of Policy:

Resource – Buckets and objects are the Amazon S3 resources for which you can allow or deny permissions. In a policy, you use the Amazon Resource Name (ARN) to identify the resource.

Actions – For each resource, Amazon S3 supports a set of operations. You identify resource operations you will allow (or deny) by using action keywords (see Specifying Permissions in a Policy). For example, the s3:ListBucket permission will allow the user permission to the Amazon S3 GET Bucket (List Objects) operation.

Effect – What the effect will be when the user requests the specific action—this can be either allow or deny. If you do not explicitly grant access to (allow) a resource, access is implicitly denied. You can also explicitly deny access to a resource, which you might do in order to make sure that a user cannot access it, even if a different policy grants access.

Principal – The account or user who is allowed access to the actions and resources in the statement. You specify a principal only in a bucket policy. It is the user, account, service, or other entity who is the recipient of this permission. In a user policy, the user to which the policy is attached is the implicit principal.

Example mentioned below contains Bucket policy which allows “tushar” an IAM user in account Account-ID:************** with relevant S3 permissions on the “buck-eu-awsfreetier-01” bucket.

Reference and for more information : https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html

{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Sid": "ExampleStatement1",
 "Effect": "Allow",
 "Principal": {
 "AWS": "arn:aws:iam::Account-ID:user/tushar" #(User tushar in account id mentioned)
 "AWS": "arn:aws:iam::AccountNumber-WithoutHyphens:root"} #(Root User)
 "AWS":"*" #(Everyone access)
 "CanonicalUser":"Amazon S3 Canonical User ID assigned to origin access identity" #(Routing to CloudFront URL)
 },

"Action": [
		 
    #Full Permission
		"*"
    #BucketBased Permissions
	    "s3:GetBucketLocation",
            "s3:ListBucket",
	    "s3:CreateBucket",
	    "s3:DeleteBucket",
	    "s3:ListBucketVersions",
	    "s3:ListAllMyBuckets",
			
    #ObjectBased Permissions
            "s3:GetObject",
	    "s3:DeleteObject",
	    "s3:GetObjectTagging",
	    "s3:GetObjectAcl",
	    "s3:PutObject",		
         ]

"Resource": [
            
"arn:aws:s3:::examplebucket"			
"arn:aws:s3:::examplebucket/developers/design_info.doc" #(ARN is for mentioning particular object in bucket)
"arn:aws:s3:::examplebucket/*" #(ARN uses the wildcard '*' to identify all objects in the bucket)
"arn:aws:s3:::*" #(All S3 resources)
"arn:aws:s3:::example?bucket/*" #(Use Wildcard ? and * to specify all objects in the bucket name which starts from example)
         ]

#The Condition  element (or  Condition block) lets you specify conditions for when a policy is in effect. In the Condition element, which is optional, you build expressions in which you use Boolean operators (equal, less than, etc.) to match your condition against values in the request
		 
#Reference & Learn More: https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html  
		 
#Bucket Policy examples : https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html 
		
#Following example is specified to make object public uploaded by specified user in principal section of the policy
		
 "Condition": {
	"StringEquals": {
	"s3:x-amz-acl": ["Public-read"]}
    }

#Following condition provides access to S3 objects and buckets via VPC endpoint
		
	"StringNotEquals": {
		"aws:sourceVpce": "vpce-1a2b3c4d"}

#Following condition provides access to S3 objects and buckets via VPC	
		
	"StringNotEquals": {
		"aws:sourceVpce": "vpce-1a2b3c4d"}
		
#Following example bucket policy allows authenticated users permission to use the s3 actions if the request originates from a specific range of IP addresses (192.168.143.*), unless the IP address is 192.168.143.188
		
	"IpAddress" : {
                 "aws:SourceIp": "192.168.143.0/24" 
                			},
        "NotIpAddress" : {
                  "aws:SourceIp": "192.168.143.188/32" 
               			 }
			
#Following condition is used to grant its user permission to create a bucket in the South America (São Paulo) Region only.
 
	 "StringLike": {
                 "s3:LocationConstraint": "sa-east-1"
            					 }
		
#Following condition is used to grant user to list objects with specific prefix only.

	 "StringEquals" : {
                 "s3:prefix": "projects" 
            					 }
		
#Following condition is used to provide MFA code to perform Permissions (Action) based on the Effect specified as "Deny" if no MFA token is not presented.
			 
      { "Null": { "aws:MultiFactorAuthAge": true }}
             
          ]
        }
      } 
      }
   ]

#Following is the specific Example on usage of MFA access, where if no MFA token is presented then don't provide access to S#

{
    "Version": "2012-10-17",
    "Id": "123",
    "Statement": [
      {
        "Sid": "",
        "Effect": "Deny",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::buck-eu-awsfreetier-01/documents/*",
        "Condition": {"Null": {"aws:MultiFactorAuthAge": true }}
      },
      {
        "Sid": "",
        "Effect": "Deny",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::buck-eu-awsfreetier-01/documents/*",
        "Condition": {"NumericGreaterThan": {"aws:MultiFactorAuthAge": 3600 }}
       },
       {
         "Sid": "",
         "Effect": "Allow",
         "Principal": "*",
         "Action": ["s3:GetObject"],
         "Resource": "arn:aws:s3:::examplebucket/*"
       }
    ]
 }

User Based Policy Examples are mentioned in the below URL

Reference: https://docs.aws.amazon.com/AmazonS3/latest/dev/example-policies-s3.html

Example:

In this example, you want to grant an IAM user in your AWS account access to one of your buckets and allow the user to add, update, and delete objects.

In addition to granting the s3:PutObject, s3:GetObject, and s3:DeleteObject permissions to the user, the policy also grants the s3:ListAllMyBuckets, s3:GetBucketLocation, and s3:ListBucket permissions. These are the additional permissions required by the console. Also, the s3:PutObjectAcl and the s3:GetObjectAcl actions are required to be able to copy, cut, and paste objects in the console.

 {
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListAllMyBuckets"
         ],
         "Resource":"arn:aws:s3:::*"
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListBucket",
            "s3:GetBucketLocation"
         ],
         "Resource":"arn:aws:s3:::examplebucket"
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:PutObject",
            "s3:PutObjectAcl",
            "s3:GetObject",
            "s3:GetObjectAcl",
            "s3:DeleteObject"
         ],
         "Resource":"arn:aws:s3:::examplebucket/*"
      }
   ]
}

AWS has made very simple to provide access to S3 using an AWS Console in IAM. Below are the steps you can follow to add the inline policy to IAM user.

  • Log in to AWS console and navigate to IAM service.
  • Select the user to whom you want to add the S3 inline access policy.

  • Navigate to permission under User and click on “Add inline policy”
  • Once you are in Editor section you can choose either to use JSON editor or GUI.
  • Select Choose Service : which will be S3 in our case.

  • Later comes the Action, here we will have to define what level of access to be assigned to this user.

  • Now we have to define on which resource (Object or Bucket) do we have give access
  • Even condition like MFA and Source IP address can be defined in this step.

Above mentioned are very few examples which i have went through using reference as S3-Developer user guide and thought are the most relevant access. If any specific access you are looking for please do let me know i will be happy to share.

Regards

Tushar Bhavsar

(AWS Solution Architect Associate)

 

 

 

Leave a reply:

Your email address will not be published.

Site Footer