Step 1: Define the IAM Role
Start in the AWS console. Go to IAM, create a new role, and select AWS service → EC2 or the service your app uses to access S3. Choose “Read-only access to S3” as the permission.
For custom control, attach a policy like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}
This ensures the role can read objects and list the bucket, but not delete or overwrite anything.
Step 2: Assign the Role to the User or Service
Attach the role to the target user, group, or service. For EC2, bind it directly to the instance profile. For serverless workflows, use the execution role. Enforce MFA for human accounts to reduce risk.
Step 3: Test Access
Use the AWS CLI or SDK to run a aws s3 ls s3://your-bucket-name command with the role’s credentials. Try fetching a file with aws s3 cp. Any write attempt should fail. Testing confirms the principle of least privilege.