5

I am in this situation where I need to have a pre-signed url to live for around a month. And since the signature v4 isn't able to deliver this, I've decided to use the V2 for now.

I have set the expiraten to one month but for some reason it expires after 1 day? (don't know the exact time it expires could be within the same day)

<Code>ExpiredToken</Code>
<Message>The provided token has expired.</Message>

And as I digged further into this, It looked like the issue could be with the X-Amz-Security-Token which expires too early. But I've no idea how to set a value to this header? (couldnt find anything about it)

Setup: Its a lambda function which generates a signed url to fetch a file from the S3. Everything is done through cloudformation. And done with the JavaScript SDK

    const s3 = new AWS.S3({
    signatureVersion: 'v2',
    region: 'eu-west-1'
});

const bucketParam = {
    Bucket: 'test-bucket',
    Key: 'testFile-1111-2222',
    Expires: 2592000
};

Any help would be appreciated

StrawHat
  • 351
  • 1
  • 6
  • 14
  • Please check `Expires` value in URL – Tuan Vo Dec 19 '19 at 08:43
  • Expires=1577253883 in this case it has been set to a week from today. – StrawHat Dec 19 '19 at 09:02
  • 1
    Did you create the presigned URL using a temporary token ? If so the URL will expire as soon as the token expires, no matter the Expires value – Daniel Dec 19 '19 at 10:53
  • What do you mean by temporary token? I haven't set any token value.. Im not sure where it comes from maybe its a default value set from an IAM role or something? I would love to manipulate it but I just dont know how to. – StrawHat Dec 19 '19 at 11:22
  • I wrote a more complete answer :) – Daniel Dec 19 '19 at 12:06

2 Answers2

6

I believe the IAM role used by Lambda is using temporary credentials, which expire before the link. According to AWS, you need to generate the presigned URL with an IAM user and signatureVersion = 4 for the link to expire after 7 days:

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.

See Why is my presigned URL for an Amazon S3 bucket expiring before the expiration time that I specified? for more details

You should try creating an IAM user to generate those URLs, and actually use its credential and assume its role (using STS) in the Lambda function in order to generate the URL. And don't forget to use signatureVersion='s3v4'.

Hope this helps

Daniel
  • 807
  • 8
  • 24
  • Thanks for your time, I do know about the answer you just wrote the issue is just I don't want to use an IAM user with credentials acess with an acces and secret acess key since it will be visible in the code. The issue with this solution without having a key management system which shouldn't expose these variables which can be used on any other machine, have the rights to get access to this bucket, since its a bucket used to personal things it shouldnt be accessible in any way!. Thats why Im trying to use the v2. But the STS is giving me an issue :-( – StrawHat Dec 20 '19 at 06:09
1

The policy "expiration" field cannot be more than 7 days beyond the "x-amz-date" field.

I found no way around this. This seems broken or at least poorly documented. The workaround seems to be to set "x-amz-date" in the future. While not intuitive this seems to be allowed, which enables you to set the expiration further in the future.

Dennis Liger
  • 1,488
  • 2
  • 13
  • 28