Certified Security - Specialty

Sign Up Free or Log In to participate!

Expiry of presigned URLs vs. expiry of STS temp creds you signed the URL with

Hi everyone,

Please imagine the following scenario:
You have an EC2 instance with an attached IAM role, which allows s3:GetObject for all objects in a specific bucket – lets say the bucket name is "presigntestbucket" and there is a file in the root of the bucket called "test.txt".

Then, you generate a presigned URL on the instance for s3://presigntestbucket/test.txt by running:

$ aws s3 presign s3://presigntestbucket/test.txt –expires-in 604800

Have a closer look at the "–expires-in" parameter. It is set to 604800 sec = 1 week. So, theoretically, the URL should be valid for one week.
The credentials used for this command come from AWS STS, because the EC2 instance will assume the role which is attached. Now, STS credentials usually expire after 1 hour by default (see: https://docs.amazonaws.cn/en_us/IAM/latest/UserGuide/id_credentials_temp_request.html ).

So, what happens, if you try to access the file "test.txt" via the generated presigned URL after 1 hour (i.e., expiry of the temporary access credentials from STS you signed the URL to the file with)?

I assume that access will be denied, since the original STS credentials, which were used to sign the URL, are expired regardless of the time you specify in the "aws s3 presign" command.

Is my assumption correct?

Kind regards,


1 Answers

I have not tested it but I am pretty sure that the URL will be invalid after the credentials expired in one hour even if signed for one week.

This is the rationale:

  • When you call the presign command you are just signing an object with a set of credentials, but nobody checks that that credentials are valid. There is no API call to AWS to presign an URL, you can disconnect your computer from the network and you will be able to presign an URL. You are just doing the math to calculate the signature, you can sign anything, you will be able to presign with regular IAM user access keys that have ben revoked years ago, you can even sign with any value in the expires-in parameter.

  • When you presign the URL you are saying to the server evaluating the GetObject API call in the future: "I allow access to this object until this day and time". But is the server who checks in the moment of access that the signature is valid, that in the moment of access those credentials have access to that object and that the expire time in the signature has not passed. A perfectly valid signature whose API Key/Secret have been deleted from IAM at the moment of access just does not work.

So, you may sign with the temporary credentials of a role, you can sign with an expiration of one week. But the validity of the signature will be evaluated in the moment of access. If the credentials have expired in that moment, or the signature has expired in that moment the request will be denied.

Corollary: If you sign something and the realize that you made a mistake just revoke the Access keys in IAM.

René Leistikow

Great and detailed answer, bcxpro – makes absolute sense. Thank you very much.


I forgot to add one thing: the principal that issued the signature with its access keys has to be able to get the object in the moment of access. If you sign now an URL and then you are denied access via a bucket policy your keys are valid but in that moment you have no access to the object.

Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!

Get Started
Who’s going to be learning?