Wintermute
Wintermute

Reputation: 3045

Getting AccessDenied error using S3 pre-signed POST

I'm trying to upload a file to S3 via a pre-signed POST, and getting a 403 AccessDenied error when I try to use the generated POST details.

I'm generating the pre-signed POST via a Lambda function. The function has an attached policy that gives it write permissions on the bucket:

"Action": [
    "s3:GetObject",
    "s3:ListBucket",
    "s3:GetBucketLocation",
    "s3:GetObjectVersion",
    "s3:PutObject",
    "s3:PutObjectAcl",
    "s3:GetLifecycleConfiguration",
    "s3:PutLifecycleConfiguration",
    "s3:DeleteObject"
],
"Resource": [
    "arn:aws:s3:::my-bucket",
    "arn:aws:s3:::my-bucket/*"
],

The bucket is currently public ("Block all public access" is OFF) and it has no bucket policy attached. It has a CORS policy allowing GET and POST from anywhere:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

The Lambda function calls the boto3 function generate_presigned_post():

s3_client = boto3.client('s3')
fields = {
    "acl": "private",
}
conditions = [
    {"acl": "private"},
]
response = s3_client.generate_presigned_post(
    Bucket='my-bucket',
    Key="${filename}",
    Fields=fields,
    Conditions=conditions)

and returns a valid-looking response:

{
    "url": "https://my-bucket.s3.amazonaws.com/",
    "fields": {
        "acl": "private",
        "key": "${filename}",
        "AWSAccessKeyId": "**********",
        "x-amz-security-token": "**********",
        "policy":"**********",
        "signature": "**********"
    }
}

I then use the response in my local Postman to construct a multipart form upload, passing the file as the "file" parameter:

Postman upload fields

And I get an AccessDenied response.

What am I overlooking? What critical step have I missed? Am I constructing the POST request correctly in Postman? Does the pre-signed POST require further configuration? How can I debug it?

EDIT:

Lambda function now has additional policy attached:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListMultipartUploadParts",
                "s3:ListBucketMultipartUploads",
                "s3:AbortMultipartUpload"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ],
            "Effect": "Allow"
        }
    ]
}

Same error persists.

Upvotes: 0

Views: 481

Answers (2)

Wintermute
Wintermute

Reputation: 3045

I'm sorry, this was a wild goose chase. I'd attached the permissions policy to the wrong function.

Upvotes: 0

omuthu
omuthu

Reputation: 6333

Add the below permissions to allow multi part uploads

s3:ListMultipartUploadParts
s3:ListBucketMultipartUploads
s3:AbortMultipartUpload

Also, ensure you add the same region in AWS Signature as the creds were created, snapshot below

AWS Signature

Upvotes: 0

Related Questions