Reputation: 741
My python (Django) application stores confidential documents and has a private bucket in AWS S3.
When you make a request for the resource, it uses boto3 to generate a pre-signed URL to be able to download the document.
The code to do so is as follows:
@staticmethod
def create_presigned_url(key_name, bucket_name=settings.AWS_PDF_STORAGE_BUCKET_NAME, expiration=60):
"""
Generate a pre-signed URL to share a PDF.
:param key_name: string.
:param bucket_name: string.
:param expiration: Time in seconds for the pre-signed url to remain valid.
:return: Pre-signed URL as a string. If error, returns None.
"""
s3_client = boto3.client('s3')
try:
response = s3_client.generate_presigned_url(
'get_object',
Params={'Bucket': bucket_name, 'Key': f"pdf/{key_name}"},
ExpiresIn=expiration
)
except ClientError:
return None
return response
When I run my application locally, it works great. It generates a link I can use to download the document and it expires after 60 seconds. Such URL looks like this:
https://BUCKETNAME.s3.amazonaws.com/pdf/testuser1/dummy.pdf?AWSAccessKeyId=ACCESSKEY&Signature=SIGNATURE&Expires=EXPIRATION"
I then deploy my application to AWS Elastic Beanstalk. All the same environment variables with AWS secrets are configured. But when I run the same request, I get a much longer URL that looks like this:
https://fiber-staging-pdfs.s3.amazonaws.com/pdf/liza/dummy.pdf?AWSAccessKeyId=ACCESSKEY&Signature=SIGNATURE&x-amz-security-token=TOKEN&Expires=EXPIRATION
Somehow, the same code when run against this environment is adding a x-amz-security-token
parameter? Why? And When I try to visit this generated URL, I get a 403 Forbidden error.
The Bucket Policy for this bucket is like:
{
"Version": "2012-10-17",
"Id": "POLICYID",
"Statement": [
{
"Sid": "SID",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNTID:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BUCKETNAME/*"
}
]
}
Upvotes: 1
Views: 1254
Reputation: 238507
Your code on your EB instance uses instance role to provide it with AWS credentials. When you do this, x-amz-security-token
is used which is a regular part of AWS credentails when you use IAM roles.
In contrast, when you run it locally, you use IAM user for AWS credentials. In that case, token is not used.
Upvotes: 1