Writing IAM Policies: How to Grant Access to an Amazon S3 Bucket
When working with Amazon S3, properly configured IAM policies are essential for maintaining security while providing necessary access to your resources. This article explains how to create IAM policies that grant specific permissions to S3 buckets and objects, covering both programmatic and console access patterns.
Policy for Programmatic Access {#policy-for-programmatic-access}
Let’s start with a policy for applications or scripts that need to interact with an S3 bucket programmatically.
Sample 1: Programmatic read and write permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::test"]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::test/*"]
}
]
}
Understanding the Policy Structure
This policy is deliberately separated into two parts for security reasons:
- Bucket-level permissions: The
ListBucketaction requires permissions on the bucket itself - Object-level permissions: The
GetObject,PutObject, andDeleteObjectactions require permissions on the objects within the bucket
We use two different Amazon Resource Names (ARNs) to precisely specify these different permission levels:
- The first Resource element (
arn:aws:s3:::test) allows applications to list all objects in the test bucket - The second Resource element (
arn:aws:s3:::test/*) allows applications to read, write, and delete any objects within the test bucket
Security Best Practice: We deliberately avoided combining these ARNs with a wildcard like arn:aws:s3:::test*. While such a pattern would grant permissions for all actions in a single statement, it would be overly permissive, potentially granting access to any bucket with a name starting with “test” (such as test-bucket or testing).
Policy for Console Access {#policy-for-console-access}
When users need to access S3 buckets through the AWS Management Console rather than programmatically, we need to extend our policy with additional permissions.
Sample 2: Enable AWS Management Console access to an Amazon S3 bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::test"]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::test/*"]
}
]
}
Why Additional Permissions Are Needed
The AWS Management Console requires more permissions than programmatic access because of how it presents S3 resources to users. Specifically:
- Bucket Discovery: The console needs to display a list of all buckets in the account, requiring the
s3:ListAllMyBucketspermission - Location Information: The
s3:GetBucketLocationpermission is needed to determine the region of each bucket
Scope and Limitations
With this policy:
- Users can see all bucket names in the account (but not their contents)
- Users can only view and modify contents of the specified “test” bucket
- Access to other buckets’ contents is denied
- The same read-write permissions from the programmatic policy are maintained
This approach follows the principle of least privilege while still providing a usable console experience.