Minimum IAM Permission to create S3 presigned URLs

If you wanted to publicly share a file or an object inside a private S3 bucket you will need to create an S3 presigned URL. This will create a temporary link to the S3 file which you can share and access publicly.

As best practice, we must apply the least privileged permission to the IAM user or IAM role that will create the S3 presigned URL. Which brings us to the question, what is the minimum IAM permission to create an S3 presigned URL?

TL;DR

You only need the action s3:GetObject to be able to create S3 presigned URLs.


Minimum IAM policy to create S3 presigned URLs

The JSON code below is the least privileged access IAM policy for creating S3 presigned URLS on your specific S3 Bucket. Just change the S3_BUCKET_NAME to the name of your S3 Bucket.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*"
    }
  ]
}

I have a private S3 Bucket name radishlogic-bucket with a file named File.txt inside. With the IAM permission above, I was able to create the S3 presigned URL of the mentioned file by running the AWS CLI command below.

aws s3 presign s3://radishlogic-bucket/File.txt

Below is the response that I got.

AWS CLI command to create S3 presigned URL

Copy and pasting the response to my internet browser gave me access to the file even if the S3 Bucket is private.


Including s3:ListBucket

The IAM policy given above has the minimum permission to create presigned URLs. If you use the IAM permission above and list down the files or objects inside your S3 Bucket you will get an Access Denied error.

You will need the ability to list down the objects to see the files names that you want to create S3 presigned URLs.

To allow the listing of files in your S3 Bucket, you will need the s3:ListBucket action in your IAM policy. Change the S3_BUCKET_NAME to your bucket name.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::S3_BUCKET_NAME",
        "arn:aws:s3:::S3_BUCKET_NAME/*"
      ]
    }
  ]
}

With the above permission given to my IAM user, I was able to list the objects in my S3 bucket named radishlogic-bucket.


Opinion on s3:GetObject as minimum IAM permission for S3 presigned URL

I find it worrying that the minimum permission to be able to create an S3 presigned URL is only s3:GetObject.

Consider the scenario that an external auditor was given access to your sensitive files in an S3 Bucket. Since they are allowed to access the files with s3:GetObject, they will be able to create presigned URLs which they can share with unintended third parties.

I wish there was a different IAM action specific only for creation of S3 presigned URLs to increase security.


I hope this helps you draft your least privileged IAM policies for creating S3 presigned URLs.

Let me know your experience in the comments below.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.