Presigned URL
A presigned URL is a link to a private stored object carrying a cryptographic signature and an expiry in its query string. Whoever holds it can read the object until it expires, with no credentials of their own.
https://bucket.s3.amazonaws.com/reports/index.html
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIA…%2F20260911%2Fus-east-1%2Fs3%2Faws4_request
&X-Amz-Date=20260911T090000Z
&X-Amz-Expires=3600
&X-Amz-SignedHeaders=host
&X-Amz-Signature=8f2c…
The signature is an HMAC over the request the URL describes — bucket, key, method, expiry. The storage service recomputes it and compares. S3 popularised the pattern; GCS signed URLs and Azure SAS tokens are the same idea.
The expiry ceilings that catch people
- Seven days is the maximum requestable lifetime under AWS Signature Version 4.
- The signing credentials' own lifetime wins. A URL signed with a
role's temporary credentials dies when that session does — frequently
one hour — no matter what
X-Amz-Expiressaid. - Which is why "I set it to seven days and it died at lunch" is a standing support question: the expiry was never the binding constraint.
They are bearer tokens
Possession is authorisation. Consequences worth stating plainly:
- Forwarding the link forwards the access. A URL pasted into a channel grants it to everyone in the channel, and to anything that indexes it.
- There is no per-recipient revocation. Killing one link means rotating the signing key or moving the object.
- There is no per-reader access log. The object access log records requests, not identities.
Why a report is the wrong payload
An HTML report is a directory, not an object. Presigning it means presigning every asset — because the entry page loads under one signature and then requests stylesheets and data files that carry none, and they 403. Workarounds exist (a bucket policy, CloudFront with a signed cookie, an origin access identity), and each one is more infrastructure between a person and a document.
Then the delivery problems remain: the link expires while the reader is on holiday, the MIME type may make the browser download rather than render it (S3 downloads instead of opening), and nobody can comment on what they read.
The alternative
A permanent URL with real access control: unlisted by default, or restricted to named people or a domain, revocable at any time, with a per-reader view record, and able to hold threads anchored to specific content in the report. No expiry to set, and no second signature for assets — they are part of the report.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.
Publish a report without presigning it →