CloudFrontの署名付きURLの仕組み

CloudFront署名付きURLの設計思想を、映画の前売り券のアナロジーから段階的に解説します。

なぜ「署名付きURL」が必要なのか

S3に置いた動画や資料を、お金を払ったユーザーだけに見せたい。よくある要件だ。

S3バケットを非公開にすればいい? それだとCloudFront経由でも配信できなくなる。CloudFrontを公開すれば誰でもアクセスできてしまう。つまり「CDNで高速配信したいが、見せる相手は制限したい」という矛盾が生まれる。

署名付きURLは、この矛盾を**「URLそのものに入場券を埋め込む」**というアプローチで解決する。

身近なたとえ: 映画の前売り券

映画館で例えると、こういうことだ:

  1. 映画館(CloudFront)は誰でも入れる場所にある
  2. だが上映室のドアには鍵がかかっている(S3は非公開)
  3. 前売り券(署名付きURL)を持っている人だけが入れる
  4. 前売り券には「3/7の19時の回まで有効」と書いてある(有効期限)
  5. 前売り券にはスタッフだけが読める偽造防止マーク(デジタル署名)がある

ポイントは、映画館側は「誰がチケットを買ったか」を知らなくていいこと。チケットが本物かどうかだけ確認すれば済む。これが署名付きURLの設計思想だ。

S3の署名付きURLとの違い

「署名付きURL」はS3にもある。混同しやすいので整理する。

共通する本質:

  • どちらも「URLに一時的なアクセス権を埋め込む」仕組み
  • 有効期限がある
  • 秘密情報(鍵)を使って署名する

CloudFront版ならではの特徴:

S3署名付きURLCloudFront署名付きURL
署名者IAMユーザーのアクセスキーRSA秘密鍵(自分で管理)
配信元S3のエンドポイント直接CloudFrontエッジ(CDN)
速度リージョンに依存エッジから配信(高速)
制御URL・期限のみURL・期限・IP制限・カスタムポリシー

つまりCloudFront版は「CDN配信 + きめ細かいアクセス制御」を両立させたもの。S3版の上位互換と考えていい。

全体像: 3つのフェーズ

署名付きURLの仕組みは、大きく3つのフェーズに分かれる。

CloudFront署名付きURLの全体フロー

フェーズ1: 鍵の準備(事前に一度だけ)

公開鍵暗号を使う。映画館のたとえでいう「偽造防止マークの仕組みを作る」段階。

  • 管理者がRSA鍵ペアを生成する(秘密鍵 + 公開鍵)
  • 秘密鍵は自分で安全に保管する(チケットに署名するための印鑑)
  • 公開鍵はCloudFrontに渡す(偽造防止マークを検証するための情報)

なぜRSAか? 署名する場所(アプリサーバー)と検証する場所(CloudFront)が別だから。秘密鍵を渡さずに検証できる公開鍵暗号が必要になる。

フェーズ2: URLの発行(リクエストのたびに)

ユーザーがコンテンツにアクセスしたいとき、アプリケーションサーバーが署名付きURLを生成する。

  1. ポリシーを作る — 「このURLに、この期限まで、このIPからアクセスOK」というJSON
  2. ポリシーをハッシュ化 — SHA-1でダイジェストを作る
  3. 秘密鍵で署名 — ダイジェストをRSAで暗号化(=デジタル署名)
  4. URLに全部くっつける — 元のURL + 署名 + キーID + 期限 = 署名付きURL

できあがったURLはこんな形になる:

https://d1234.cloudfront.net/video.mp4
  ?Expires=1686873600
  &Signature=ABCxyz...(Base64エンコードされた署名)
  &Key-Pair-Id=KPID1234

フェーズ3: アクセスと検証(ユーザーがURLを使うとき)

  1. ユーザーが署名付きURLにアクセスする
  2. CloudFrontがURLのパラメータを読む
  3. Key-Pair-Id から対応する公開鍵を取得
  4. 公開鍵で署名を検証(改ざんされていないか確認)
  5. ポリシーの条件を確認(有効期限内か、IPは合っているか)
  6. すべてOKなら → S3からコンテンツを取得して配信
  7. NGなら → 403 Forbidden

CloudFrontは署名の正当性だけを確認する。ユーザーが誰かは知らないし、知る必要がない。映画館がチケットの偽造防止マークだけ確認するのと同じだ。

設計のポイント

この仕組みの設計で巧みなのは、責務の分離にある:

  • アプリケーションが「誰にアクセスさせるか」を判断する(認証・認可)
  • CloudFrontは「このURLが本物か」だけ判断する(署名検証)

CloudFrontはユーザー管理を一切しない。だからどんな認証基盤とも組み合わせられる。Cognito、Auth0、自前の認証、なんでもいい。「誰に署名付きURLを渡すか」はアプリ側の責任だ。

Hugo で構築されています。
テーマ StackJimmy によって設計されています。