Amazon S3 の署名付き URL (presigned URL) をマネジメントコンソールからお手軽に生成できるようになっていた

2 クリックくらいで署名付き URL を生成できます。有効期限の考え方については注意してください。

コンバンハ、千葉(幸)です。

2022年の1月27日に AWS の中の人からこんなツイートがありました。

S3 コンソールから署名付き URL を簡単に生成できるようになったよ、という内容です。

具体的には署名付き URL 生成のオブジェクトアクションが追加されており、2回くらいポチポチするだけで生成できます。

そのうち AWS アップデートとして発表されるかな、と思っていたのですが、1ヶ月くらい経っても音沙汰が無いので勝手に取り上げることにします。

AWS ドキュメントは更新されていた

Github から過去の更新履歴を確認してみると、2022年1月14日の時点で更新が入っていました。

ダウンロード用の署名付き URL の生成方法として S3 コンソールが追加されています。

そしてこの更新に対応する更新履歴は確認できませんでした。ちょっと寂しいですね。

S3 の署名付き URL とは何か

S3 の署名付き URL は、プライベートなオブジェクトもしくはバケットへのアクションを可能にさせるものです。ここでのアクションとはアップロードかダウンロードを指します。

IAM ユーザーや IAM ロールなどの認証情報を使用して署名付き URL を生成し、その URL を連携すれば任意のユーザーがアクションを実行できます。

ユーザーが多数の場合、それぞれに対して認証情報(IAM ユーザーなど)を用意するのは手間がかかります。代わりに署名付き URL を提供することで一時的なファイルの授受を簡便に行えます。セミナーの参加者に一定期間ファイルを配布したい、サイズの大きなファイルの受け渡しを S3 バケットへのアップロードで行いたい、というケースがあるでしょう。

署名付き URL の生成は基本的に AWS SDK を使用して行います。ダウンロード用の URL に関しては AWS CLI や AWS Explorers でも生成できます。今回新しくマネジメントコンソールでも(正式な手段として)対応しました。

アップロード用の URL 生成は変わらず AWS SDK でのみ対応しています。

署名付き URL についての詳細は以下エントリもあわせてご参照ください。

S3 コンソールから署名付き URL を生成してみた


2022/4/26追記 コンソールから生成できるURLの有効期限が最大で12時間に変更されていました。以降の記述は執筆当時のものです。


物は試しということでやってみます。具体的な操作方法は以下に記載があります。

今回は以下の条件で行います。

  • S3 コンソールを操作するのは IAM ロール(スイッチロール後)
  • 署名付き URL を生成するオブジェクトのContent-Typetext/plain

S3 コンソールでオブジェクトを選択した状態で「アクション」→「署名付き URL で共有」を押下します。

s3_presigned-url

(ちなみにオブジェクトの詳細画面からでも OK です。)

s3_object_pre-signed_url

署名付き URL の生成画面に遷移します。7 日間を上限に、各種時間間隔で有効期間を指定できます。

  • 分(1~10080)
  • 時間(1~168)
  • 日(1~7)

今回は 1 日間を指定して生成します。

s3_pre-signed_url_generate

生成が完了するとクリップボードに URL がコピーされています。改めてコピーすることも可能です。

s3_presigned_url_copy

生成された URL をデコードして改行を挟むと以下のような構成になっています。有効期限が 86,400秒、つまり 1 日間で指定されていることが分かります。

https://chibayuki-hoge-hoge.s3.ap-northeast-1.amazonaws.com/test.txt
 ?response-content-disposition=inline
 &X-Amz-Security-Token=IQoJb3JpZ2luX2VjE以下略
 &X-Amz-Algorithm=AWS4-HMAC-SHA256
 &X-Amz-Date=20220226T122030Z
 &X-Amz-SignedHeaders=host
 &X-Amz-Expires=86400
 &X-Amz-Credential=ASIAQ3BIIH73ZQHRKS6P/20220226/ap-northeast-1/s3/aws4_request
 &X-Amz-Signature=7097492484e4ca以下略

クリップボードにコピーされた URL を新規に立ち上げたシークレットウインドウにペーストして接続すると、S3 オブジェクトの中身が問題なく参照できました。

s3_presigned_url_hello

この URL を共有すれば任意のユーザーに一定期間プライベートなコンテンツを提供できます。

今回の URL は 24 時間より早く有効期限になる

有効期限 1 日間 を指定して生成したので、この URL を 24 時間利用できると勘違いしてしまうかも知れません。

実際にはそれより早くこの URL は使用できなくなります。

URL を生成してから 1 時間程度 経過した後にアクセスすると、以下のようにエラーが発生しました。

presigned-url_expired

<Error>
  <Code>ExpiredToken</Code>
  <Message>The provided token has expired.</Message>
  <Token-0>IQoJb3JpZ2luX2VjE以下略</Token-0>
  <RequestId>A17VN78SWC6ARH3Z</RequestId>
  <HostId>vTTBI5+3pLXtqCyzr9SBzieAvHVdHyF3IJg6sYSYmKxGD8IgAuFVnLdkvpumJJ1af13QosIb3Co=</HostId>
</Error>

ポイントは、スイッチロールしてから URL を生成した点です。IAM ロールには最大セッション時間という考え方があります。今回使用した IAM ロールは最大セッション時間 は 1 時間で設定されています。

署名付き URL によるアクションはそれを生成した IAM エンティティによるものとして扱われます。今回の IAM エンティティは IAM ロールではなく「IAM ロールを引き受けたセッション」であるため、そのセッションが有効期限切れになれば署名付き URL も使用できなくなります。

こういった考え方については以下で詳しく取り上げられています。

また、各種方式ごとの「 IAM ロールを引き受けたセッションの有効期限」は以下にまとまっています。

いずれの場合でも最大で 12 時間であるため、IAM ロールを用いて署名付き URL を生成する場合はその有効期限の上限も 12 時間となります。S3 コンソールでの生成時にそれより長い期間を指定しても無駄となりますので、覚えておくとよいでしょう。

お手軽な署名付き URL の生成って「開く」のことかと思った

タイトルを見てそんな風に思った方がいるかも知れません。これが何を言っているかと言うと、以下を押下した場合を指します。

s3_console_open

上記を実行すると、署名付き URL の生成 + アクセスが同時に行われます。生成された URL をデコードして改行を挟むと以下のようになります。

https://chibayuki-hoge-hoge.s3.ap-northeast-1.amazonaws.com/test.txt
 ?response-content-disposition=inline
  &X-Amz-Security-Token=IQoJb3JpZ2luX2VjE以下略
  &X-Amz-Algorithm=AWS4-HMAC-SHA256
  &X-Amz-Date=20220226T091834Z
  &X-Amz-SignedHeaders=host
  &X-Amz-Expires=300
  &X-Amz-Credential=ASIAQ3BIIH73YW64LU7F/20220226/ap-northeast-1/s3/aws4_request
  &X-Amz-Signature=2c3f07bda1d以下略

先述の URL と同じ形式になっており、有効期限が 5 分となっていることが分かります。

「開く」は前から実行可能でしたので、つまりは S3 コンソールからの署名付き URL の生成は以前から可能でした。生成できるというのが正式に紹介されていたわけではないので、知る人ぞ知るという立て付けだったかも知れません。

「署名付き URL で共有」アクションによって正式に、なおかつ有効期限を指定して生成できるようになりました。

いろんなファイルのパターンごとに「開く」を試しているエントリがありますので、合わせてご参照ください。

終わりに

S3 コンソールからダウンロード用の署名付き URL を生成してみました。いざ実装されてから考えると、なぜ今までできなかったのかが不思議なくらい あって然るべしな機能な気がします。

署名付き URL を用いたダウンロード(GetObject)は署名付き URL を生成した IAM エンティティによるものと扱われるため、権限が不足する(生成した後に IAM ポリシーをデタッチするなど)とダウンロードが失敗する、といった注意事項を踏まえた上でご活用ください。

ここまで来るとアップロード用の署名付き URL も S3 コンソールから生成できてもいいのでは、という気もします。残念ながらいまだに AWS SDK でのみしか対応していないので、使用する場合には以下のように一工夫が必要です。

いつの日か実装されそうな気もするので、気長に待ちましょう。

以上、 チバユキ (@batchicchi) がお送りしました。