Skip to content
Latchkey

aws s3 presign: Generate a Temporary S3 URL

aws s3 presign produces a signed URL that grants time-limited access to an object without handing over AWS credentials.

A presigned URL lets a downstream job, a browser, or a partner fetch or upload an object with a link that expires. In CI it is a clean way to hand a build artifact to a step or system that has no AWS credentials of its own.

What it does

aws s3 presign generates a URL that embeds a signature derived from your credentials, valid until it expires. Anyone with the URL can perform the operation (GET by default) until then, with no further authentication. The default expiry is 3600 seconds.

Common usage

Terminal
aws s3 presign s3://my-bucket/artifacts/build.tar.gz --expires-in 900
# capture the URL for a later job to download
URL=$(aws s3 presign s3://my-bucket/reports/coverage.html --expires-in 3600)
echo "coverage=$URL" >> "$GITHUB_OUTPUT"

Options

FlagWhat it does
--expires-in <seconds>Lifetime of the URL (default 3600, max 604800)
--region <region>Region for the signature
--endpoint-url <url>Presign against an S3-compatible endpoint

In CI

Keep --expires-in as short as the workflow needs; a presigned URL is a bearer token, so a long expiry in logs is a leak. If you presign with temporary role credentials (OIDC/STS), the URL stops working when those credentials expire, even if --expires-in is longer, so the STS session length is the real cap.

Common errors in CI

A URL that returns "The request signature we calculated does not match" (SignatureDoesNotMatch) usually means the region used to sign differs from the bucket region; pass --region. "(AccessDenied)" from the URL means the signing identity lacked s3:GetObject. A URL that suddenly 403s before --expires-in elapsed means the temporary STS credentials that signed it expired first.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →