Course outline · 0% complete

0/27 lessons0%

Course overview →

Presigned URLs: temporary access

lesson 4-3 · ~9 min · 12/27

The middle ground

Your app stores each user's invoices in a private bucket. The user clicks Download. Now what? The bucket must stay private, but this one person needs this one file, right now.

Bad option 1: make the bucket public. Lesson 4-2 covered how that ends.

Bad option 2: stream the file through your own server, private bucket → server → user. It works, but every download now costs your server memory and bandwidth, twice.

The S3 answer is a presigned URL. Your server, which does have S3 access through its role (lesson 2-3), uses its credentials to sign a URL that says: whoever holds this exact link may GET this exact object until this exact time. The user's browser then downloads straight from S3. The signature is part of the URL, so S3 can verify it without the user having any AWS identity at all.

browseryour serverhas an IAM roleS3 bucketprivate1. GET /download2. signed URL, expires in 300s3. GET with signature, straight from S3
Presigned flow: the server signs (using its role credentials), the browser fetches directly from S3, and after the expiry time the link is worthless.

Code exercise · bash

S3's expiry check is simple arithmetic on timestamps (seconds). A URL was signed at time 800 with a 300-second lifetime, and a request arrives at time 1000. Run the check S3 performs.

Code exercise · bash

Your turn. A user bookmarked a presigned link signed at time 800 with a one-hour lifetime (3600 seconds) and clicks it at time 5000. Update the variables and predict the outcome before running.

Quiz

Presigned URLs also work for uploads (PUT). Why would an app hand the browser a presigned upload URL instead of accepting the file itself and forwarding it to S3?