简体   繁体   中英

Boto3 InvalidAccessKeyId in generate_presigned_post

I'm creating an AWS Lambda and API using Python's Chalice library. My AWS Credentials are injected using github workflow aws-actions and its able to chalice deploy . The endpoints are working and it's deploying perfectly to AWS.

The problem is:

I use Boto3 to create a presigned upload form using its function generate_presigned_post located in docs here: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html

But when I use the response from that function and generate an html with it, after submitting the files to upload, it returns me

<Error>
<Code>InvalidAccessKeyId</Code>
<Message>
The AWS Access Key Id you provided does not exist in our records.
</Message>

I checked everything and it seems it's using wrong AWS_ACCESS_KEY but if it's deploying to AWS perfectly, I figured it isn't the issue (at least for now). I use boto3 client and it seems to locate aws credentials automatically but it seems that it does not locate mine (or whatever is happening) and provides a wrong AWS_ACCESS_KEY.

import boto3

S3_CLIENT = boto3.client('s3')
BUCKET = 'bucket_name'

response = S3_CLIENT.generate_presigned_post(
            BUCKET,
            Key="{$filename}",
            Fields=None,
            Conditions=None,
            ExpiresIn=3600
        )

It returns correct response but when integrated with a form and used, the form returns the error.

This is actually a little bit more complicated than it seems because of the nature of lambda and temporary keys. Suffice to say you should follow these steps:

  1. Create an IAM role with permissions to generate presigned urls for the bucket in question.

  2. Take a lambda basic execution role and add permissions for that role to assume the role in step 1.

  3. In your boto3 code, add a step to assume the role in step 1 before generating the signed url. Something like this:

    import boto3

    sts_client = boto3.client('sts')

    assumed_role_object = sts_client.assume_role( RoleArn='arn_of_role_to_assume' )

    credentials = assumed_role_object['Credentials']

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

    s3_client.generate_presigned_url......

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM