I’m learning AWS and with my limited knowledge of AWS, am I right in saying that If I make pre-signed URLS to Upload and Download from a bucket – which is set to block all public access it should work? I take all my authentication and checks through API gateway, so if a user is able to hit the endpoint that returns a pre-signed URL to upload/download, then they are allowed to do so.
If I’m correct then I am confused to why I’m getting an Access denied
error when I try to upload an image to my bucket (which blocks public access) via a pre-signed URL – it works perfectly when the bucket is set to public?
My Lambda function that creates a pre-signed URL:
const AWS = require('aws-sdk'); AWS.config.update({region: process.env.AWS_REGION}); const s3 = new AWS.S3() // Main entry point exports.handler = async (event) => { const result = await getUploadURL() // console.log('Result: ' result) return result; } const getUploadURL = async function(){ const randomID = parseInt(Math.random()*10000000000) const s3Params = { Bucket: process.env.UploadBucket, Key: `${randomID}.jpg`, ContentType: 'image/jpeg', ACL: 'public-read' } console.log('getUploadURL: ', s3Params) return new Promise((resolve, reject) => { // Get signed URL resolve({ "statusCode": 200, "isBase64Encoded": false "body": JSON.stringify({ "uploadURL": s3.getSignedUrl('putObject', s3Params), "photoFilename": `${randomID}.jpg` }) }) }); }
My python code that get’s pre-signed URL and uses it to upload objects:
def upload_file_new(fileDir): presignedURL = requests.get('<URL>').json()['uploadURL'] data = open(fileDir, 'rb').read() result = requests.put(presignedURL, data=data, headers={'Content-type': 'image/jpeg'})
My policy for my lambda function:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::contentsync/*" } ] }
Advertisement
Answer
It’s likely that your bucket has Block all public access
turned on. Therefore, you cannot set the ACL of the object to public-read
. The solution is that you can either turn off the Block all public access
or change public-read
to private
.