I use the following approach (AWS sdk v3 Javascript) in my lambda function:
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3"; const client = new S3Client({ region }); // perhaps we can pass here credentials of IAM user const command = new GetObjectCommand({ Bucket: bucket, Key: key }); const url = await getSignedUrl(client, command, { expiresIn: 4320000 }); // I expect that link will expire in 5 days
But the problem is the link expires in ~12-14hours. Here is the fragment of cloudformation template:
Resources: LambdaFunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "sts:AssumeRole" Path: "/" GetPresignedUrlFunction: Type: AWS::Serverless::Function Properties: FunctionName: !Sub "get-presigned-url-${EnvName}" Handler: getPresignedUrl.handler Role: !GetAtt LambdaFunctionRole.Arn
Should I use credentials of IAM user for S3Client constructor options like:
const client = new S3Client({ region, credentials: { accessKeyId: 'test', secretAccessKey: 'test' }});
Thank you for your comment. We'll review and update the Knowledge Center article as needed.
I am having the same issue when using S3.getSignedUrl in a lambda function (I am using aws sdk v2) . Although I specify the "Expires" parameter as a value that equals 1 year , the signed URL is no longer accessible after about 12 hours or so. The lambda function uses an IAM role that has GetObject permissions on the bucket. The error received upon accessing the URL after 12 hours or so, is : <Code>ExpiredToken</Code><Message>The provided token has expired.</Message>
The post above says "If you created a presigned URL using a temporary token, then the URL expires when the token expires. This is true even if the URL was created with a later expiration time." Although the signed URL contains an AccessKeyID in the URL, I did not generate it or any temporary token explicitly, just simply used the SDK in a lambda that assumes a role. However , the default expiry for the "session" that generated the URL is not 7 days, it is not even 24 hrs. How do I change that.
Thank you for your comment. We'll review and update the Knowledge Center article as needed.

I could not believe that the solution was to create an IAM user therefore I wanted an alternative approach.
I have "fixed" this problem by creating a Lambda with a function url. The lambda function listens to HTTP GET requests.
When executed it creates a pre-signed url in real time and then redirects the requester to the pre-signed url using a 302 status code and location header. The lambda function has a querystring that has expiry, object key and a salted hash of the key. The expiry date is also signed to ensure it cannot be tampered with. Before the pre-signed url is created the code verifies the signatures and ensures the querystring parameters have not been altered.
Thank you for your comment. We'll review and update the Knowledge Center article as needed.

Relevant content
- asked 7 months ago
- asked 5 months ago
- asked 7 years ago
- asked a year ago
- AWS OFFICIALUpdated 3 months ago
- AWS OFFICIALUpdated 8 months ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated 2 years ago