In this series of tutorials, we have learned how to upload files to S3 and list all files from S3. But we still have not talked about how to grant public read access to S3 objects using python.

By default, all objects when uploaded to S3 will be private, and except the owner of that object, no one will be able to view that file. In many cases, you will want to give the general public to view that file for example, when we are sharing images or using S3 as our static data hosting service.

In this blog, we will learn about different access control lists (ACLs) for objects in S3, and how we can list these ACLs for some objects. We will also learn how we can use python, boto3, and set_object_access_policy functions to grant public read access to s3 objects.

Setting up permissions for S3

For this tutorial to work, we will need an IAM user who has access to upload a file to S3. We can configure this user on our local machine using AWS CLI or we can use its credentials directly in python script. We have already covered this topic on how to create an IAM user with S3 access. If you do not have this user setup please follow that blog first and then continue with this blog.

What are ACLs

AWS S3 provides predefined grants that we can assign to buckets or objects to give them different access levels. These grants are known as Access Control Lists (ACLs). The below table list down all ACLs available with the access levels they grant on object or bucket.

You can learn more about ACLs in AWS Documentation. Now that we are familiar with ACLs, let us learn how we can use them with S3 objects. We can also use these with S3 buckets but we will cover that in another blog.

Listing ACLs on s3 object

First, we will write python code to list all grants or ACLs present on some object in S3. We can use the get_object_access_policy function from the boto3 client to list ACLs for objects.

def get_object_access_policy():
    This function prints ACL policy for object in S3 bucket
    :return: None
    s3_client = boto3.client("s3")
    bucket_name = "testbucket-frompython-2"
    object_key = "test9.txt"

    response = s3_client.get_object_acl(


When we run the above function we will see the below output that is an array of ACLs on the object. As mentioned before, by default there is a “private” ACL on any object in S3 and it grants full access to the owner.

[{'Grantee': {'ID': 'a601289bf62bcd8a0fccb6ff6efa66fc234208dd2efa7d
              'Type': 'CanonicalUser'},
  'Permission': 'FULL_CONTROL'}]

When the object has a “private” ACL attached to it, no one will be able to read that object. We can easily test this. When we click on the object and its URL from the S3 console we will see the below error.

Can not read private objects in s3 bucket

I am trying to read the test9.text file from my s3 bucket but as it has private ACL attached, we see the above page with access denied error. This can be changed by attaching “public-read” ACL to the object. Let us learn how we can do that.

Grant public read access to S3 objects

Now that we want to add public read access to our file so that we can share a link with someone, let us learn how we can do that using python.

def set_object_access_policy():
    This function adds ACL policy for object in S3 bucket.
    :return: None
    s3_client = boto3.client("s3")
    bucket_name = "testbucket-frompython-2"
    object_key = "test9.txt"

    response = s3_client.put_object_acl(
        ACL="public-read", Bucket=bucket_name, Key=object_key

When we run this code, the “test9.txt” file in the S3 bucket will have public read access and if we click on its link, we can see the below output.

Once an object has a public-read policy, we can read it


In this tutorial, we have learned how to list objects access list (ACLs) and how to add ACLs to S3 objects using python and boto3. I hope you have found this useful. In the next blog, we will learn how to add bucket-level policies. See you there.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *