jschneier / django-storages

https://django-storages.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
2.7k stars 847 forks source link

AWS Lambda, InvalidAccessKeyId, still a problem due to None, v1.14.3 #1401

Closed nitsujri closed 1 week ago

nitsujri commented 2 months ago

Problem

Tickets https://github.com/jschneier/django-storages/issues/1353 and https://github.com/jschneier/django-storages/issues/1361 was hoped to be fixed by https://github.com/jschneier/django-storages/pull/1336 for AWS Lambda/ECS where you can automatically use AWS_SESSION_TOKEN, but for me it does not.

I got help from AWS Support because I was really confused about where the problem was as it initially appeared as if the Execution Role could list buckets but not read into them and only when I hard coded KeyId+Secret did it work (I think that's what #1353 found too).

Using v1.14.3 I get this error from Django: An error occurred (InvalidAccessKeyId) when calling the PutObject operation: The AWS Access Key Id you provided does not exist in our records.

AWS Support provided logs where the Actor has a <null> in it:

Request ID: THSGEJHE4B91AKFA
--------
End Time (UTC): 2024-05-08 09:29:22.857
Time Taken: 6 msecs
Response Code: 403
Error Code: InvalidAccessKeyId
Bucket Owner: 322209459496
Actor: ASIAUWBJOFUUBQ2HYIGM/<null>
Requester: Malformed
--------

This is a working request using boto3.Session().client("s3") directly and ListBuckets.

Request ID: S6V8SYWH8DK9DN9A
--------
End Time (UTC): 2024-05-07 23:44:05.635
Time Taken: 257 msecs
Response Code: 200
Requester Account: 322209459496
Requester Type: IAM ROLE
Actor: ASIAUWBJOFUUNZBIAUC5/AROAUWBJOFUUOI5PKDP3U:CoreAppStageStack-WebsiteLambda
Requester: AROAUWBJOFUUOI5PKDP3U
--------

Hack My application relies on the default boto3.Session (all S3 Buckets use the same Execution Role). So this hack works great:

class HackS3Storage(S3Storage):
    def _create_session(self):
        import boto3

        return boto3.Session()

Root Issue It seems like Boto3 sets the credentials terribly for a session if you directly, but only pass AWS_SESSION_TOKEN.

Honestly I'm unsure what the fix is.

Thanks for this great library though!

jschneier commented 2 months ago

Did you see #1399? It added pulling the session_token from the env as well. Does that resolve the issue?

mstathers commented 2 months ago

EDIT: Never mind, it looks like this change is unreleased as of 1.14.3.

@jschneier I just installed 1.14.3 into a fresh venv via pip and storages/backends/s3.py's get_default_settings() is still:

            "security_token": setting(
                "AWS_SESSION_TOKEN", setting("AWS_SECURITY_TOKEN")
            ),

Maybe something went wrong with the release?

nitsujri commented 2 months ago

Did you see #1399? It added pulling the session_token from the env as well. Does that resolve the issue?

Did I not reply to this? So sorry. I tested it the next day and it worked great. Can't wait for the release.

khamaileon commented 1 month ago

I have the same problem with version 1.14.3. My code runs on AWS Lambda and access to S3 is done via an access policy. So Boto doesn't need any config. But from the error message, it looks like a config has been passed.

An error occurred (InvalidAccessKeyId) when calling the PutObject operation: The AWS Access Key Id you provided does not exist in our records.

khamaileon commented 1 month ago

Ok I tried the master version and it's working 🍾

@jschneier, can you release a new version please ? It's a pretty critical bug imho.

jschneier commented 1 week ago

New release is now out.