简体   繁体   中英

AWS boto3 InvalidAccessKeyId when using IAM role

I upload to and download from S3 with a presigned post/url. The presigned url/post are generated with boto3 in the Lambda function (it is deployed with zappa).

While I add my AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID as env variable works perfectly. Then I removed my credentials and I add an IAM role to lambda to full access to S3 bucket. After that the lambda return with the presigned URL and getObject is working well, however when i want to upload object through the URL, it returns an InvalidAccessKeyId error. The used key id ASIA... which means those are temporary credentials.

It seems that the lambda does not use IAM role, or what is the problem?

class S3Api:

    def __init__(self):
            self.s3 = boto3.client(
                's3',
                region_name='eu-central-1'
            )

    def generate_store_url(self, key):
        return self.s3.generate_presigned_post(FILE_BUCKET,
                                               key,
                                               Fields=None,
                                               Conditions=None,
                                               ExpiresIn=604800)

    def generate_get_url(self, key):
        return self.s3.generate_presigned_url('get_object',
                                              Params={'Bucket': FILE_BUCKET,
                                                      'Key': key},
                                              ExpiresIn=604800)

My result for sts:getCallerIdentity :

{
     'UserId': '...:dermus-api-dev',
     'Account': '....',
     'Arn': 'arn:aws:sts::....:assumed-role/dermus-api-dev-ZappaLambdaExecutionRole/dermus-api-dev',
    'ResponseMetadata': {
        'RequestId': 'a1bd7c31-0199-472e-bff7-b93a4f855450',
        'HTTPStatusCode': 200,
        'HTTPHeaders': {
            'x-amzn-requestid': 'a1bd7c31-0199-472e-bff7-b93a4f855450',
            'content-type': 'text/xml',
            'content-length': '474',
            'date': 'Tue, 09 Mar 2021 08:36:30 GMT'
        },
        'RetryAttempts': 0
    }
}

dermus-api-dev-ZappaLambdaExecutionRole role is attached to dermus-api-dev lambda.

Presigned URLs and the Lambda credentials work in a non-obvious way together.

From the docs , emphasis mine:

  • Anyone with valid security credentials can create a presigned URL. However, in order to successfully access an object, the presigned URL must be created by someone who has permission to perform the operation that the presigned URL is based upon.

  • The credentials that you can use to create a presigned URL include:

    • IAM instance profile: Valid up to 6 hours

    • AWS Security Token Service: Valid up to 36 hours when signed with permanent credentials, such as the credentials of the AWS account root user or an IAM user

    • IAM user: Valid up to 7 days when using AWS Signature Version 4

  • To create a presigned URL that's valid for up to 7 days, first designate IAM user credentials (the access key and secret access key) to the SDK that you're using. Then, generate a presigned URL using AWS Signature Version 4.

  • If you created a presigned URL using a temporary token, then the URL expires when the token expires, even if the URL was created with a later expiration time.

Bottom line: The URL might be expired if you wait too long, because the Lambda functions credentials are already expired.

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