aws s3 presignで署名付きURL(presigned URL)を生成すると、期限付きでダウンロードできるURLをその場で作れる。
URLを受け取った相手にAWSアカウントは不要で、期限が過ぎればURLは自動的に使えなくなる。
基本的な使い方
aws s3 presignにS3のURIを渡すと署名付きURLを出力する。
$ aws s3 presign s3://<bucket-name>/<object-key>
実行例
$ aws s3 presign s3://example-bucket/path/to/report.pdf
https://example-bucket.s3.ap-northeast-1.amazonaws.com/path/to/report.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20260731%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20260731T222635Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=089d9f242e031bbe70caf246719c15e8577d7fb0362d04654befb78d974b9d81
出力されたURLはブラウザで開くか、curlでダウンロードできる。
$ curl -o report.pdf "https://example-bucket.s3.ap-northeast-1.amazonaws.com/path/to/report.pdf?X-Amz-Algorithm=..."
URLには&が含まれるため、シェルで扱う際はダブルクォートで囲む。
クォートを付けないとシェルが&をバックグラウンド実行として解釈してしまう。
有効期限を指定する
--expires-inで有効期限を秒数で指定する。
指定しない場合のデフォルトは3600秒(1時間)である。
5分だけ有効なURLを生成する例
$ aws s3 presign s3://example-bucket/path/to/report.pdf --expires-in 300
指定できる最大値は604800秒(7日)である。
$ aws s3 presign s3://example-bucket/path/to/report.pdf --expires-in 604800
URLに含まれるパラメータ
生成されたURLのクエリ文字列には署名情報が含まれる。
| パラメータ | 内容 |
|---|---|
| X-Amz-Algorithm | 署名アルゴリズム。AWS4-HMAC-SHA256固定 |
| X-Amz-Credential | 署名に使ったアクセスキーID、日付、リージョン、サービス名 |
| X-Amz-Date | 署名した日時(UTC) |
| X-Amz-Expires | 有効期限の秒数 |
| X-Amz-SignedHeaders | 署名対象のヘッダー |
| X-Amz-Signature | 署名 |
| X-Amz-Security-Token | 一時的な認証情報を使った場合のセッショントークン |
URLが失効する時刻はX-Amz-DateにX-Amz-Expires秒を足した時刻である。
起点は配布した時刻ではなく生成した時刻である。あらかじめ生成しておくと、相手が受け取った時点では残り時間が減っている。
期限切れのURLにアクセスした場合
期限を過ぎたURLにアクセスするとAccessDeniedが返る。
$ curl "https://example-bucket.s3.ap-northeast-1.amazonaws.com/path/to/report.pdf?X-Amz-Algorithm=..."
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Request has expired</Message><X-Amz-Expires>1</X-Amz-Expires><Expires>2026-07-31T22:27:50Z</Expires><ServerTime>2026-07-31T22:27:53Z</ServerTime><RequestId>CWMH4K7B9JN5DNF2</RequestId><HostId>...</HostId></Error>
Expiresが失効時刻、ServerTimeがアクセスした時刻である。
なお、期限の判定はHTTPリクエストの時点で行われる。
大きなファイルのダウンロード中に期限を過ぎても、そのダウンロードは継続する。
最大値を超える期限を指定した場合
--expires-inに604800より大きい値を指定してもコマンドはエラーにならず、URLを生成する。aws s3 presignはAWSへのリクエストを送らず、手元で署名を計算するだけのためである。
$ aws s3 presign s3://example-bucket/path/to/report.pdf --expires-in 604801
https://example-bucket.s3.ap-northeast-1.amazonaws.com/path/to/report.pdf?...&X-Amz-Expires=604801&...
生成されたURLは使えず、アクセスした時点でエラーになる。
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AuthorizationQueryParametersError</Code><Message>X-Amz-Expires must be less than a week (in seconds); that is, the given X-Amz-Expires must be less than 604800 seconds</Message><RequestId>X8SGEPH74TFFJZYY</RequestId><HostId>...</HostId></Error>
エラーメッセージは604800未満と読めるが、604800ちょうどは受け付けられる。
コマンドが成功してもURLが有効とは限らないため、配布する前に自分でアクセスして動作を確認しておくとよい。
一時的な認証情報では7日間有効なURLを作れない
署名付きURLは、生成に使った認証情報が失効した時点で無効になる。--expires-inに7日を指定していても、認証情報の期限が先に来ればそちらが優先される。
| 認証情報 | URLの有効期間 |
|---|---|
| IAMユーザーのアクセスキー | 最大7日 |
| STSの一時的な認証情報(AssumeRoleなど) | セッションの期限まで(デフォルト1時間) |
| EC2インスタンスプロファイル | ロールの認証情報の期限まで(おおむね6時間) |
| ECSタスクロール | ロールの認証情報の期限まで(1〜6時間) |
IAM Identity Center(旧AWS SSO)やaws sts assume-roleで得た認証情報も一時的な認証情報にあたる。
これらの認証情報で生成したURLは、X-Amz-Security-Tokenパラメータを含む。
指定した期限より早くURLが使えなくなる場合は、まず認証情報の種類を確認するとよい。
長期間有効なURLが必要な場合はIAMユーザーのアクセスキーで生成する。
ただし期限を長くするほど、URLが流出した際に悪用される期間も長くなる。共有に必要な期間だけを指定する。
リージョンの指定
署名にはリージョンが含まれるため、バケットのあるリージョンを指定して生成する。
プロファイルのデフォルトリージョンとバケットのリージョンが異なる場合は--regionで明示する。
$ aws s3 presign s3://us-east-1-bucket/path/to/report.pdf --region us-east-1
リージョンが一致しない場合、生成されるURLも別リージョンのエンドポイントを指すため、アクセス時にPermanentRedirectなどのエラーになる。
権限はURLを生成した人のものになる
署名付きURLは、生成したIAMユーザーやIAMロールの権限でリクエストする。s3:GetObjectの権限を持たない状態で生成したURLは、アクセスすると403を返す。
コマンドが成功してもダウンロードできるとは限らない。
また、URLを持っている人は誰でもファイルをダウンロードできる。
期限内であれば何度でも使えるうえ、転送されたURLも同じように機能する。
URLそのものが鍵として働くため、パスワードと同等の扱いで共有する。
より厳しく制限したい場合は、バケットポリシーのs3:signatureAge条件で署名からの経過時間を制限したり、aws:SourceIpでアクセス元を制限したりできる。
ダウンロード専用である
aws s3 presignで生成できるのはGET用のURLのみである。
アップロード用のPUTのURLはAWS CLIでは生成できず、boto3のgenerate_presigned_urlのようなSDKの機能を利用する。
参考
- presign - AWS CLI Command Reference
- Download and upload objects with presigned URLs - Amazon S3
- AWS CLIでS3のファイルをcatしたい
