AWS Security Blog

Writing IAM Policies: How to Grant Access to an Amazon S3 Bucket

February 20, 2025: This post was republished to reflect the updated least privilege permissions necessary for read-write access to Amazon S3.

In this post, we’ll address a common question about how to write an AWS Identity and Access Management (IAM) policy to grant read-write access to an Amazon S3 bucket. Doing so helps you control who can access your data stored in Amazon S3.

You can access S3 buckets programmatically or by using the AWS Management Console. For example, consider an application that allows users to upload and view photos. When users upload a photo, the app makes an API call to store the photo in an S3 bucket. When users view their gallery, the app makes another API call to retrieve the photos from the bucket. We’ll explore two types of permissions: one that grants access to interact with Amazon S3 by using direct API calls, and another that allows users to manage their files through the AWS Management Console. While both methods rely on API calls in the background, the key difference is how users interact with the system: directly through API calls or through a web-based interface (the console). Let’s go through the two permissions in detail.

Policy for Programmatic Access

The following sample IAM policy grants programmatic read-write access to an S3 bucket named amzn-s3-demo-bucket:

Sample 1: Programmatic read and write permissions

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket"]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket/*"]
    }
  ]
}
JSON

The policy is separated into two parts. The first part of the policy grants the s3:ListBucket permissions on the bucket itself, specified by the Amazon Resource Name (ARN) arn:aws:s3:::amzn-s3-demo-bucket. This action allows applications to list all the objects in the amzn-s3-demo-bucket bucket. The second part grants permissions to interact with the objects in the bucket. Specifically, it allows the actions s3:GetObject, s3:PutObject, and s3:DeleteObject on all objects in the bucket, specified by the ARN arn:aws:s3:::amzn-s3-demo-bucket/*.

Policy for Console Access

To enable console access, we need to update the policy to grant broader permissions. Specifically, the ListAllMyBuckets action is required to display the bucket navigation interface. This action allows users to list all buckets in the account.

Sample 2: Enable AWS Management Console access to an Amazon S3 bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListAllMyBuckets"],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket"]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket/*"]
    }
  ]
}
JSON

With the additional statement, users can view the amzn-s3-demo-bucket bucket by using the console. Without this permission, access is denied even if users have the correct bucket-specific permissions. The ListAllMyBuckets action allows users to lists all buckets in the account, but users cannot view the contents of other buckets. The read-write permissions are specified only for the amzn-s3-demo-bucket bucket, just like in the previous policy. If a user tries to view another bucket, access is denied. This approach follows the principle of least privilege while still allowing for a functional console experience.

When accessing S3 resources, both identity-based policies (IAM) and resource-based policies (such as bucket policies) are evaluated together—an explicit deny in either policy type will override an allow. Additionally, your IAM policy might be subject to a permissions boundary. Permissions boundaries are an advanced feature for using a managed policy to set the maximum permissions that an identity-based policy can grant to an IAM entity. Lastly, if your AWS account is part of an organization, service control policies (SCPs) and resource control policies (RCP) might restrict permissions across multiple AWS accounts, even if your IAM policy explicitly allows an action. When you troubleshoot access issues, consider each of these layers of access control.

Following these policy examples and understanding the differences between programmatic and console access requirements can help you to create least-privilege IAM policies and secure your S3 buckets while maintaining the functionality you need for both applications and users. For more information about IAM policies and Amazon S3, see the following resources:

 
If you have feedback about this post, submit comments in the Comments section below. If you have questions about this post, contact AWS Support.
 

Laura Verghote Laura Verghote
Laura is a Senior Solutions Architect for public sector customers in the Europe, Middle East, and Africa (EMEA) region. She works with customers to design and build solutions in the AWS Cloud, bridging the gap between complex business requirements and technical solutions. She joined AWS as a technical trainer and has wide experience delivering training content to developers, administrators, architects, and partners across EMEA.