← AWSサービスの内部原理 コース
104. 署名付きURLとOACは2枚の通行証である — ビューワーの入口とオリジンの裏口を別々に閉める
キャッシュから速く配りつつ、選ばれた人にだけ配る——CloudFrontのプライベート配信を「守るべきドアが2つある」という一点で図に追っていきます。
① まず「守るドアが2つある」ことを見る
ビューワー利用者のブラウザ
ドア(B) 裏口 — S3を非公開のまま、CloudFrontにだけ取りに来させる
CloudFrontエッジキャッシュ
S3バケット非公開・オリジン
- (A)を守る仕組み = 署名付きURL / 署名付きCookie(誰に配るかをアプリが決める)
- (B)を守る仕組み = OAC(origin access control。S3を非公開のまま裏口だけ開ける)
- 公式は「オリジンサーバー(S3等)へ直接アクセスするURLではなく、CloudFront URL経由でのアクセスを強制する」ことを推奨。この2ドアは別々の問題であり、別々の仕組みで閉める
プライベート配信は「入口(A)」と「裏口(B)」という機能の異なる2つの境界の話であり、片方を守っても配信は守れない。まずこの2枚の通行証を分けて考えることが出発点。
② ドア(A):署名付きURLと署名付きCookie
アプリが認可判定利用者がログイン/課金済みか
2つの渡し方
鍵で署名信頼キーグループ(trusted key groups)の鍵を使う
CloudFrontが署名を検証
署名付きURLURL自体に署名を埋め込む
個別ファイルを1つずつ制御したい/クライアントがcookie非対応署名付きCookieSet-Cookieヘッダで署名をブラウザに持たせる
複数ファイルをまとめて許可(会員エリア全体)/現在のURLを変えたくない通過者だけ配信署名のない/不正なリクエストは通さない
- 公式は署名者として「trusted key groups(信頼キーグループ)と trusted signers のうち、trusted key groups を推奨」と明記(We recommend that you use trusted key groups)
- 公式の使い分け基準 — 署名付きURL: 個別ファイルへのアクセスを制限したい(例: アプリのインストーラのダウンロード)、クライアントがcookieに対応していない。署名付きCookie: 複数の制限ファイルへのアクセスをまとめて提供したい(例: HLS動画の全ファイル・会員エリア全体)、現在のURLを変えたくない
- アプリは「Set-Cookieヘッダで署名付きCookieを発行する」か「署名付きURLで応答する」かで認可ユーザーに応える
- 補足: 両方を併用した場合、署名付きURLが署名付きCookieより優先される
(A)の本質は「URL(またはCookie)自体を資格情報にする」capability設計。S3編で学んだ署名付きURL——URLを持っていること自体がアクセス権——が、CDNの入口として再登場する。
③ ドア(B):OACでS3を非公開のまま開ける
CloudFrontエッジS3へのリクエストにSigV4で署名
CloudFormationでは SigningProtocol: sigv4 / SigningBehavior: always(常に署名)バケットポリシーで判定
S3バケット公開設定はオフのまま
両方一致したときだけ
PrincipalService: cloudfront.amazonaws.com
ConditionAWS:SourceArn = 自分のディストリビューションARN
s3:GetObject許可不一致なら拒否
- 公式のバケットポリシー例(読み取り専用): Sid: AllowCloudFrontServicePrincipalReadOnly / Principal: Service = cloudfront.amazonaws.com / Action: s3:GetObject / Condition: StringEquals で AWS:SourceArn = arn:aws:cloudfront::111122223333:distribution/<CloudFront distribution ID>
- 公式は「常に署名する(Sign requests / always)」を推奨設定とする。この設定を選んだときに限り、CloudFront↔S3の通信は常にHTTPSになる
- SourceArn条件は「そのディストリビューションを代理するリクエストのときだけ」バケットを開けるための鍵穴
OACは、SigV4(リクエストへの署名)とリソースポリシー(誰を許可するか)の合わせ技そのもの。認証暗号編で別々に学んだ2つの部品が、S3を非公開に保つ裏口の錠前として組み合わさる。
④ 旧方式OAIはなぜレガシーか
OAI(旧方式)特別なCloudFront IAMユーザーをPrincipalに許可
OACに置き換えると
✗ SSE-KMSKMSで暗号化したオブジェクト
✗ オプトインリージョン2023年1月以降の新リージョン含む
✗ 動的リクエストPUT / POST / DELETE
上のすべてに対応
OAC(推奨)サービスプリンシパル + SourceArn条件 + SigV4
○ 全リージョン2022年12月以降のオプトインリージョン含む
○ SSE-KMSKMSキーのポリシーにCloudFrontを足せば配れる
○ PUT / DELETEread/writeのバケットポリシー例あり
- SSE-KMSオブジェクトを配るKMSキーポリシー例: Sid: AllowCloudFrontServicePrincipalSSE-KMS / Principal: Service = cloudfront.amazonaws.com / Action: kms:Decrypt, kms:Encrypt, kms:GenerateDataKey* / Condition: AWS:SourceArn = 自分のディストリビューションARN
- 公式は「OAC instead(OACを代わりに使うことを推奨)」と明記。OAIはこれらの機能をサポートしないか、追加の回避策が要る
OAIとOACの違いは「対応範囲」で捉えると速い。暗号化(SSE-KMS)・書き込み(PUT/DELETE)・新リージョンを扱うならOAC一択。裏口の錠前をリソースポリシー+SigV4方式に統一したのがOACだと理解する。
⑤ 締め:2枚とも閉めて初めてプライベート配信
(A)署名だけ(B)OACなし → S3が公開のまま残る
S3のURLを直接叩けば署名(A)を素通りできる(B)OACだけ(A)署名なし → 入口が開けっ放し
CloudFront経由なら誰でも見られ、「認可した人だけ」が効かない初めて成立
両方閉じるOACでS3非公開+CloudFront URL経由を強制+入口を署名で守る
プライベート配信選ばれた人にだけ、キャッシュから配る
- 公式の締めの推奨(1): 利用者にはCloudFront URLでアクセスさせ、オリジンサーバー(S3等)を直接叩くURLは使わせない——必須ではないが「署名付きURL/Cookieの制限を回避されるのを防ぐため推奨する(we recommend it to prevent users from bypassing the restrictions)」
- 公式の締めの推奨(2): その上で署名付きURL/署名付きCookieで入口を制御する
「機能の異なる2つの境界を、別々の仕組みで守る」——これはAPI Gateway編のTLS終端と認可を分けた構図、Step Functions編のタスクトークン(推測不能な合言葉=権利)と同型の、多層防御の考え方そのもの。2枚の通行証は、片方では通行証にならない。