cloud jockey
cloud jockey

Reputation: 258

AWS STS to list buckets gives access denied

I have a bucket with empty bucket policy, block public access turned ON (ACLs and Bucket) and trying to list buckets using IAM policy tied to user using STS AssumeRole with following attached policy.

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

The assumed role credentials are used during the STS session in python (boto3)

s3c = boto3.client('s3',
  aws_access_key_id=credentials['AccessKeyId'],
  aws_secret_access_key=credentials['SecretAccessKey'],
  aws_session_token=credentials['SessionToken'])

s3c.list_buckets()

I get this exception:

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

When I tried to use IAM Policy simulator, it indicates "Implicitly denied". Im thinking if I need to access a bucket policy for this user? My understanding has been if both IAM and Bucket policy, it is an intersection. If either is not present, the other takes precedence.

Upvotes: 0

Views: 2355

Answers (2)

John Rotenstein
John Rotenstein

Reputation: 270294

Calling list_buckets() uses the s3:ListAllMyBuckets permission.

This permission cannot be restricted to a specific bucket. A user can either list all of the buckets in the account, or none of them.

Calling operations on a bucket (ListBucket, GetBucket*) requires permission for the bucket itself.

Operations on objects requires permission for the objects (or /* after the bucket name to permit actions on all objects).

Therefore, you can change your policy to:

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

Upvotes: 4

Jason Wadsworth
Jason Wadsworth

Reputation: 8885

This is a pretty common issue because people tend to miss the difference between a "bucket" resource and an "object" resource. A bucket ends in the name of the bucket (arn:aws:s3:::my-test-bucket) whereas an object includes the bucket and key, and is often granted with a star after the initial slash. So, just change your policy to the following.

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

Upvotes: -1

Related Questions