AWS
S3
Presigned URL
AWS CLI
Cloud Storage

How to Generate a Presigned S3 URL via AWS CLI

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

A presigned S3 URL gives temporary access to an S3 object using the permissions of the AWS identity that generated it. In the AWS CLI, the standard command is aws s3 presign, which signs an object URL for a limited amount of time.

Basic Command

Generate a URL for one object:

bash
aws s3 presign s3://my-bucket/images/photo.jpg --expires-in 3600

This creates a URL that is valid for one hour.

The --expires-in value is in seconds, so:

  • '60 means one minute'
  • '3600 means one hour'
  • '86400 means one day'

What the Command Requires

The CLI must already have usable AWS credentials and the caller must have permission to access the object. The presigned URL does not grant new permissions; it temporarily delegates the permissions the signing identity already has for that object.

Check your CLI identity first if needed:

bash
aws sts get-caller-identity

Include the Region When Needed

If the bucket is in a region that differs from your CLI default configuration, specify it explicitly:

bash
aws s3 presign s3://my-bucket/images/photo.jpg \
  --expires-in 3600 \
  --region us-east-1

That helps avoid signing mismatches and confusing authorization errors.

What the URL Is Good For

A presigned URL is useful when:

  • An object is private in S3
  • You want to share temporary download access
  • You do not want to hand AWS credentials to the recipient

The recipient can use the URL in a browser, with curl, or from application code until the expiration time is reached.

Example:

bash
curl "https://my-bucket.s3.amazonaws.com/images/photo.jpg?X-Amz-Algorithm=..."

Security Considerations

A presigned URL is still a credential-bearing URL for the duration of its validity. Anyone who gets it can use it until it expires.

So best practice is:

  • Keep the expiration as short as practical
  • Share it only over secure channels
  • Avoid logging it casually in long-lived server logs if that creates unnecessary exposure

This matters because the URL is functionally a temporary access token embedded in a link. Treat it with the same care you would give any other short-lived credential.

There is also a practical ceiling to expiration. In the AWS CLI flow, presigned URLs are meant for temporary sharing, not indefinite access. If you find yourself wanting very long-lived links, that is usually a sign that bucket policy, CloudFront signed URLs, or an application-level access pattern would be a better fit.

Understand the Scope of the CLI Command

The basic aws s3 presign workflow is best known for download-style object access. If your use case involves more specialized request types or a custom application flow, many teams switch to an SDK so they can generate presigned requests inside application code with tighter control over method, headers, and expiration behavior.

That distinction matters in practice. The CLI command is excellent for one-off operational tasks, support work, and quick validation. Once presigning becomes part of a product feature, generating URLs inside application code is usually easier to test, audit, and evolve.

Common Pitfalls

  • Forgetting that the signing identity must already have object access.
  • Using the wrong region when generating the URL.
  • Setting an unnecessarily long expiration time.
  • Treating the presigned URL like a permanent public link.

Summary

  • Use aws s3 presign s3://bucket/key --expires-in N to generate a presigned S3 URL.
  • The URL grants temporary access using the permissions of the signer.
  • Use the correct region if your bucket is not in the CLI's default region.
  • Keep expiration short and handle the generated URL like a temporary secret.
  • Presigned URLs are a sharing mechanism, not a replacement for long-term object access policy design.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.