Skip to content

How to Grant Public Read Access to S3 Objects

Posted on:October 1, 2023 at 05:17 AM

In this tutorial series, we have learned how to upload files to S3 and list all files from S3. However, we have yet to discuss how to grant public read access to S3 objects using Python.

By default, all objects, when uploaded to S3, will be private, and no one can view that file except the owner of that object. In many cases, you will want to give the general public a chance to view that file, for example, when we share images or use 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 to 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 use its credentials directly in Python script. We have already covered 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 table below lists all available ACLs and the access levels they grant on objects or buckets.

ACLApplies toPermissions added to ACL
bucket-owner-readcan be added to the ObjectObject owner gets FULL_CONTROL. The bucket owner gets READ access. If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.
bucket-owner-full-controlcan be added to the ObjectBoth the object owner and the bucket owner get FULL_CONTROL over the object. If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.
log-delivery-writecan be added to the ObjectThe LogDelivery group gets WRITE and READ_ACP permissions on the bucket.
privatecan be added to Bucket and objectOwner gets FULL_CONTROL. No one else has access rights (default).
public-readcan be added to Bucket and objectOwner gets FULL_CONTROL. The AllUsers group gets READ access.
public-read-writecan be added to Bucket and objectThe owner has FULL_CONTROL. The AllUsers group has READ and WRITE access. It is generally not recommended to grant this on a bucket.
aws-exec-readcan be added to Bucket and objectOwner gets FULL_CONTROL. Amazon EC2 gets READ access to GET an Amazon Machine Image (AMI) bundle from Amazon S3.
authenticated-readcan be added to Bucket and objectOwner gets FULL_CONTROL. The AuthenticatedUsers group gets READ access.

You can learn more about ACLs in AWS Documentation. Now that we are familiar with ACLs let us learn how to 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 S3 objects. To list ACLs for objects, we can use the get_object_access_policy function from the boto3 client.

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(
        Bucket=bucket_name,
        Key=object_key,
    )

    pprint(response["Grants"])

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

[{'Grantee': {'ID': 'a601289bf62bcd8a0fccb6ff6efa66fc234208dd2efa7d
076551ea907cbf0cff',
              '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 quickly test this. We will see the error below when we click on the object and its URL from the S3 console.

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 a private ACL attached, I get the access denied error above. I can change this by attaching a “public-read” ACL to the object. Let’s learn how to do that.

Grant public read access to S3 objects

Now that we want to add public read access to our file to share a link with someone let us learn how to 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
    )
    pprint(response)

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 output below.

can-read-public-read-objects-from-s3

Conclusion

This tutorial taught us how to list objects access lists (ACLs) and add ACLs to S3 objects using Python and boto3. I hope you have found this helpful. In the next blog, we will learn how to add bucket-level policies. See you there.