I use boto3 to generate a presigned URL for an S3 object
S3_CLIENT = boto3.client('s3')
PRESIGNED_URL_EXPIRY_SECONDS = 7*24*3600
def generate_presigned_url(bucket_name, object_key, expiration):
"""
Generates a pre-signed URL for an S3 object.
Args:
bucket_name (str): The name of the S3 bucket.
object_key (str): The key of the S3 object.
expiration (int): The expiration time of the pre-signed URL, in seconds.
Returns:
str: The pre-signed URL for the S3 object.
Raises:
ClientError: If there is an error generating the pre-signed URL.
"""
try:
response = S3_CLIENT.generate_presigned_url(
'get_object',
Params={
'Bucket': bucket_name,
'Key': object_key
},
ExpiresIn=expiration
)
except ClientError as e:
print(e)
return None
return response
and then the method is called
media_presigned_url = generate_presigned_url('s3-bucket','s3-object-key', PRESIGNED_URL_EXPIRY_SECONDS)
The method generates a presigned url such as
https://s3-bucket.s3.amazonaws.com/lskdjfeur_2023-02-18_03-05-50.jpg?AWSAccessKeyId=ASXXXXXXXE&Signature=0n%2FYQXXXXXXXX5Re3DX%2FLNzq504%3D&x-amz-security-token=IXXXXJb3J%3D&Expires=1678160873
The Expires=1678160873 indicates that this should be expiring in about a week.
But the issue is that the presigned URL is expiring much earlier than that i.e. less than a day.
<Code>ExpiredToken</Code>
<Message>The provided token has expired.</Message>
My goal is to generate a presigned URL that would expire in a week.
What could be causing this presigned URL to expire earlier than that ?
2
Answers
Your AWS IAM user policy may affect the max expiration setting
A pre-signed URL is similar to a normal URL that points to an object in Amazon S3, but it includes a signature that authorizes access to the private object.
The signature is generated from the Secret Key of a set of AWS Credentials. These credentials could be associated with an IAM User, an IAM Role or temporary credentials generated by the AWS Security Token Service (STS).
The pre-signed URL uses the permissions of those credentials to authorize access to the object. However, if the underlying credentials do not have the necessary access, or if those credentials have expired, then access to the object will be denied.
To provide a real-life analogy, I could write a bank check that authorises the bank to transfer my money to you. However, if an unauthorized person signs the check, then the bank is not meant to pay the money. Or, if the check was issued by an on behalf of a company and the accountant who makes the checks lost their job with the company, then the unemployed accountant should not be able to issue any more checks for the company.
In your situation:
generate_presigned_url()
, using those temporary credentialsTo prevent this happening, use permanent credentials to generate the pre-signed URL (or temporary credentials that won’t expire during the expiry period of the pre-signed URL). You could store these credentials in AWS Systems Manager Parameter Store and the Lambda function could retrieve the credentials before generating the pre-signed URL.