I have a python code to use pandas to read s3 files located at
s3://bucket_name/table_name/file.parquet
If I provide the pull path with file name like above, my python works.
But if I provide the directory path as the prefix to list all objects and then get each object, I get the access denied error:
bucket=bucket_name
key=table_name/
objects=s3.list_objects(Bucket=bucket,Prefix=key)['Contents']
print(objects)
dfs=[]
for obj in objects:
file_key=obj['Key']
obj=s3.get_object(Bucket=bucket,Key=file_key)
df_single=pd.read_parquet(BytesIO(obj['Body'].read()))
dfs.append(df_single)
df=pd.concat(dfs, ignore_index=True)
I got the error in the title.
I checked the IAM policy for the bucket. we allow for s3.ListBucket and s3.getObject for the bucket "s3://bucket_name*/*"
UPDATE
updated the policy by adding the resource without ‘/*’ as shown below.
and attached this policy to the role that I use as the executing role of the lambda function (which runs the script)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucketMultipartUploads",
"s3:GetBucketTagging",
"s3:ListBucketVersions",
"s3:ListBucket",
"s3:GetBucketAcl",
"s3:BypassGovernanceRetention",
"s3:GetBucketPolicy",
"s3:ListMultipartUploadParts",
"s3:PutObject",
"s3:GetObjectAcl",
"s3:GetObject",
"s3:ObjectOwnerOverrideToBucketOwner",
"s3:DescribeJob",
"s3:PutObjectVersionAcl",
"s3:PutBucketAcl",
"s3:PutBucketPolicy",
"s3:DeleteAccessPointPolicy",
"s3:DeleteObject",
"s3:PutAccessPointPolicy",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::bucket_name",
"arn:aws:s3:::bucket_name*/*"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:GetAccessPoint",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource": "*"
}
]
}
run the script:
s3_resource=boto3.resource('s3')
bucket = s3_resource.Bucket(bucket_name)
for obj in bucket.objects.all():
print(obj.key)
get the error
[ERROR] ClientError: An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied
2
Answers
Please note that
ListBucket
requires permissions on the bucket (without/*
) whileGetObject
applies at the object level and can use*
wildcards.Also, if you are granting access to an IAM User or IAM Role in the same AWS Account, it is better to grant permissions via an IAM Policy on the IAM User/Role instead of using a Bucket Policy.
This IAM Policy can be applied to the IAM User/IAM Role and grant access to the whole bucket to that user:
If you were to use a Bucket Policy (not advisable), you would need to add a
Principal
to identify who receives access:These policies can be further restricted to only grant access to a specific directory if desired. See: Bucket policy examples – Amazon Simple Storage Service
To reproduce your situation, I did the following:
BUCKET-NAME
for the actual bucket name):aws configure --profile stack
aws s3 ls --profile stack
— it successfully listed the contents of my bucketmy-bucket-name
for the actual bucket name):If your results are different, you might want to compare the above steps to what you have done.