Reputation: 245
I wrote a lambda function who return a pre-signed url for documents in S3 Buckets.
The code is really simple :
const url = s3.getSignedUrl('getObject', {
Bucket: BUCKET_NAME,
Key: myFile.Key,
Expires: 20
})
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({
"url": url
}),
};
The funny thing is when I call this function locally (with serverless framework) like this :
sls invoke local -f getEconomyFile -d '{ "queryStringParameters": { "key": "myfile.pdf" } }'
It's working ! I have a url which give me the file.
But when I deploy to AWS Lambda, the function return a URL which always says "access denied" on the file :
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>93778EA364B3506B</RequestId>
<HostId>
yqnPC0SeIVE3/Pl7/d+xHDJ78=
</HostId>
</Error>
Why is it working locally and not deployed ?
Thank you !
Upvotes: 7
Views: 12911
Reputation: 78898
Here's a list of things to check when pre-signed URLs do not work:
s3:GetObject
permission on the relevant object ARN such as arn:aws:s3:::BUCKET-NAME/*
).arn:aws:s3:::BUCKET-NAME/*
or arn:aws:s3:::BUCKET-NAME/images/*
. It is a common mistake to indicate a bucket-level ARN such as arn:aws:s3:::BUCKET-NAME
but that will not work.Even if your IAM credentials do not permit access to the S3 object(s), it is possible to use those credentials to create a pre-signed URL (a purely local computation**) but that URL will not actually allow you to access the object because the credentials underpinning the pre-signed URL do not have access to the object.
** you can tell this is a local computation and does not involve any calls into AWS by pre-signing an object such as s3://notmybucket/cat.png
. That will work and generate a pre-signed URL, but it will not actually be usable to retrieve that object.
Upvotes: 22
Reputation: 19152
https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-owner-full-control-acl/
As access to a bucket is given to other accounts, if they put an object in the bucket, the account owner doesn't get automatic access to those put files. To fix this you need to add this to your commands:
--acl bucket-owner-full-control
Such as
aws s3api put-object --bucket accountB-bucket --key example.txt --acl bucket-owner-full-control
or
aws s3 cp s3://accountA-bucket/test.txt s3://accountB-bucket/test2.txt --acl bucket-owner-full-control
Otherwise you leave the ACL for the object hyper specific to the other account and user that pushed the file.
Hope that helps.
Upvotes: 0