概要
Amazon CloudFrontを使用してS3バケットのコンテンツを配信する場合、S3バケットへの直接アクセスをブロックし、CloudFront経由のアクセスのみを許可する構成が求められます。この要件を実現するための仕組みとして、従来は Origin Access Identity(OAI)が使用されてきましたが、現在は後継の Origin Access Control(OAC) が推奨されています。
本記事では、OACがなぜ推奨されるのか、OAIとの技術的な違い、署名動作の選択肢、バケットポリシーの正しい構成、そしてOAIからOACへの移行パスについて解説します。OAIの基本的な概念については、S3とCloudFrontを使った静的サイトの公開:CloudFrontからのみアクセスする方法を参照してください。

クラウドおさるS3 オリジンを CloudFront 経由だけに絞る仕組みを、レガシーの OAI ではなく後継の OAC で組み直して確かめる記事でござる。署名動作の選び方とバケットポリシーの書き方まで、順に見ていくのでござるな。
この記事のメリット
- OAIとOACの機能差を比較表で正確に把握できる
- OACが推奨される技術的理由(SigV4署名、全リージョン対応、SSE-KMS対応、動的リクエスト対応)を理解できる
- OACの3つの署名動作オプションの使い分けを理解できる
- OAC用のS3バケットポリシーの正しい記述方法を習得できる
- CloudFrontディストリビューションIDをPrincipalに指定する方式やIAMユーザーを使用する方式が推奨されない理由を説明できる
- OAIからOACへの移行手順を把握できる
- SCS試験のCloudFrontオリジン保護に関する問いに正確に答えられるようになる
執筆者とキャラクター紹介
執筆者:土肥(とひ)
株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。


クラウドおさる



はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。



基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。



猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。
技術解説
OAI(Origin Access Identity)の制限事項
OAIはCloudFront経由でのみS3バケットにアクセスさせる仕組みとして長年使用されてきましたが、以下の制限事項があります。
- リージョンの制約: 2022年12月以降に追加されたAWSリージョンではOAIが使用できない
- SSE-KMS非対応: AWS KMSで暗号化されたS3オブジェクトにアクセスできない
- GETとHEADのみ対応: PUT、DELETE、PATCHなどの動的リクエストに対応していない
- レガシーな仕組み: OAI は CloudFront が管理する特別なユーザー(オリジンアクセスアイデンティティ)をバケットポリシーの
Principalに指定する方式で、現在は後継の OAC を使うことが推奨されている
これらの制限を解消するために、OACが導入されました。
OACとOAIの比較
| 項目 | OAI(Origin Access Identity) | OAC(Origin Access Control) |
|---|---|---|
| 認証の仕組み | CloudFront が管理する特別なユーザー(OAI)を Principal に指定 | CloudFront がリクエストに SigV4 署名を付与 |
| 対応リージョン | 2022年12月以前のリージョンのみ | すべてのAWSリージョン |
| SSE-KMSサポート | 非対応 | 対応 |
| 対応HTTPメソッド | GET、HEAD | GET、HEAD に加えて PUT、DELETE などの動的リクエスト |
| バケットポリシーのPrincipal | OAI固有のARN | サービスプリンシパル(cloudfront.amazonaws.com) |
| アクセス制御の条件 | なし | AWS:SourceArnでディストリビューションを特定 |
| 署名動作の設定 | なし | 3つのオプションから選択可能 |
| 対応オリジンタイプ | S3のみ | S3、MediaStore、MediaPackage v2、Lambda関数URL、VPCオリジン |
| ステータス | レガシー(非推奨) | 推奨 |
OACが推奨される理由
新規構築でOACが推奨される主な理由は以下の通りです。
- SigV4署名の使用: OACはAWS Signature Version 4(SigV4)を使用してリクエストに署名します。SigV4はAWSの標準的な認証方式であり、すべてのAWSリージョンで使用できます
- SSE-KMS暗号化への対応: S3バケットにAWS KMS(
aws:kms)で暗号化されたオブジェクトが格納されている場合でも、OACを通じてアクセスできます。OAIではKMS暗号化されたオブジェクトにアクセスできないため、別途対策が必要でした - 動的リクエストへの対応: OACはPUT、DELETEといったHTTPメソッドにも対応しており、S3へのファイルアップロードやオブジェクト削除をCloudFront経由で行う構成が実現できます
- セキュリティの強化:
AWS:SourceArn条件を使用して、特定のCloudFrontディストリビューションからのアクセスのみを許可できます。OAIでは条件による制約がなく、同一アカウント内の他のディストリビューションからもアクセスが可能でした


OACの署名動作オプション
OACを作成する際に、署名動作(Signing behavior)を選択できます。3つの値があり、ユースケースに応じて使い分けます。
| API/CLI の値 | コンソールの表記 | 説明 | ユースケース |
|---|---|---|---|
always | 「署名リクエスト (推奨)」 | CloudFrontがオリジンへのすべてのリクエストに署名を付与する | S3オリジンへのアクセスをCloudFront経由のみに制限する一般的なケース(推奨) |
never | 「リクエストに署名しない」 | CloudFrontはリクエストに署名を付与しない | オリジンが独自の認証を行う場合、またはパブリックアクセスが許可されたオリジンの場合 |
no-override | 「署名リクエスト (推奨)」+「認証ヘッダーを上書きしない」 | ビューワーのリクエストにAuthorizationヘッダーが含まれていない場合のみ署名を付与する。含まれている場合はそのまま転送する | ビューワーが独自の認証情報をオリジンに送信する必要がある場合 |
コンソールの「署名動作」はラジオボタン2つ(「リクエストに署名しない」「署名リクエスト (推奨)」)で表示され、no-override は「署名リクエスト (推奨)」を選んだうえで、その下の「認証ヘッダーを上書きしない」チェックボックスをオンにすることで指定します。
S3オリジンの保護を目的とする場合は、always(「署名リクエスト (推奨)」のみを選択した状態)を使用します。



S3 オリジンを守るなら署名動作は always、コンソールでは「署名リクエスト (推奨)」だけを選んだ状態でござる。no-override はビューワーの Authorization ヘッダーがあればそのまま転送するので、目的が違うのでござるな。
OAC用のS3バケットポリシー
OACを使用する場合、S3バケットポリシーではサービスプリンシパル cloudfront.amazonaws.com をPrincipalに指定し、AWS:SourceArn条件で特定のCloudFrontディストリビューションからのアクセスのみを許可します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipalReadOnly",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket-name/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/EXXXXXXXXXX"
}
}
}
]
}ポイント:
Principalにサービスプリンシパルを指定することで、CloudFrontサービス全体を信頼しますAWS:SourceArn条件により、許可するCloudFrontディストリビューションを1つに特定します。この条件がないと、同一アカウント内のすべてのCloudFrontディストリビューションからアクセスが可能になってしまいます- PUTやDELETEも許可する場合は、
Actionにs3:PutObjectやs3:DeleteObjectを追加します



AWS:SourceArn の条件を外すと、同じアカウント内のどのディストリビューションからでも読めてしまうのでござる。猿山のバナナ倉庫も「監視当番なら誰でも可」にしたら、よその持ち場の当番まで入れてしまうでござろう。ディストリビューションを 1 つに特定するまでがセットでござるぞ。
推奨されないアプローチとその理由
S3オリジンへのアクセスをCloudFront経由に制限する方法として、OAC以外のアプローチが検討されることがありますが、以下の理由から推奨されません。
CloudFrontディストリビューションIDをPrincipalに直接指定する方式
バケットポリシーでCloudFrontディストリビューションのARNをPrincipalとして直接指定する方法は、S3バケットポリシーではサポートされていません。PrincipalにはIAMユーザー、IAMロール、AWSアカウント、またはAWSサービスプリンシパルのみを指定できます。
IAMユーザーを作成してCloudFrontに認証情報を持たせる方式
IAMユーザーのアクセスキーをCloudFrontに設定してS3にアクセスする方法は、以下の問題があります。
- アクセスキーの管理が必要になり、キーのローテーションを定期的に行う運用負荷が発生する
- アクセスキーが漏洩した場合のセキュリティリスクが高い
- CloudFrontにはIAMユーザーの認証情報を設定する仕組みが用意されていない
OACはこれらの課題をすべて解決し、AWSが推奨するマネージドな方式でS3オリジンを保護します。
OAIからOACへの移行パス
既存のCloudFrontディストリビューションでOAIを使用している場合、OACへの移行は以下の手順で行えます。移行中もダウンタイムは発生しません。
- OACを作成する: CloudFrontコンソールまたはAPIでOACを新規作成する
- ディストリビューションのオリジン設定を更新する: OAIからOACに切り替える
- S3バケットポリシーを更新する: OAI用のポリシー(OAIのARNをPrincipalに指定)を、OAC用のポリシー(サービスプリンシパルと
AWS:SourceArn条件を使用)に変更する - 動作確認: CloudFront経由でのアクセスが正常に動作することを確認する
- OAIを削除する: 移行が完了したら、不要になったOAIを削除する
移行時の注意点として、S3バケットポリシーの更新とディストリビューションの設定変更を同時に行うことが推奨されます。バケットポリシーのみを先に更新すると、OAI経由のアクセスが失敗する可能性があります。移行期間中は、OAI用とOAC用の両方のステートメントをバケットポリシーに記述しておくことで、安全に移行できます。
実践
前提条件
以下のリソースが作成済みであること。
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| S3バケット | oac-demo-bucket-<アカウントID> | CloudFrontのオリジンとなる静的コンテンツ格納用 |
S3バケットには、動作確認用のHTMLファイル(index.html)がアップロードされていることを前提とします。index.htmlの内容は任意ですが、以下のような簡易的な内容で構いません。
<!DOCTYPE html>
<html>
<head><title>OAC Demo</title></head>
<body><h1>CloudFront OAC Demo Page</h1></body>
</html>S3バケットの「ブロックパブリックアクセス」設定は、すべてのオプションが有効(ブロック)の状態にしておきます。
OACの作成
AWSマネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します(CloudFront はグローバルサービスですが、オリジンとなるS3バケットは東京リージョンに作成しています)。
上部の検索バーに CloudFront と入力し、表示された「CloudFront」を選択します。
左側ナビゲーションの「オリジンアクセス」を選択します。
「コントロール設定を作成」をクリックすると、「コントロール設定を作成」ダイアログが開きます。以下の内容を入力します。
- 名前:
oac-demo-s3-access - 説明 – オプション:
OAC demo for S3 origin protection - 署名動作:
署名リクエスト (推奨)(「認証ヘッダーを上書きしない」チェックボックスはオフのままにします) - オリジンタイプ:
S3 - 「Use SigV4a signing protocol」はオフのままにします


「Create」をクリックします。
OACが作成され、一覧に表示されることを確認します。
CloudFrontディストリビューションの作成
左側ナビゲーションの「ディストリビューション」を選択し、「ディストリビューションを作成」をクリックします。
ディストリビューションの作成は5つのステップに分かれています。
ステップ1「Choose a plan」では、料金プランを選択します。ここでは従量課金の「Pay as you go」を選択し、「Next」をクリックします(月額固定のプランはWAFやDNSなどをまとめた有料プランです)。
ステップ2「Get started」では、ディストリビューション名に oac-demo と入力し、「Next」をクリックします。
ステップ3「Specify origin」では、オリジンとセキュリティ保護の設定を行います。
- S3 origin:
oac-demo-bucket-<アカウントID>.s3.ap-northeast-1.amazonaws.com(「Browse S3」からバケットを選択できます) - Origin path – optional: 空欄のままにします
- 「Allow private S3 bucket access to CloudFront – Recommended」にチェックを入れます
- オリジン設定:
Use recommended origin settings - キャッシュ設定: デフォルトのままにします


現在の作成ウィザードには、既存のOACを選択する項目がありません。「Allow private S3 bucket access to CloudFront」にチェックを入れると、CloudFrontがこのディストリビューション専用のOACを自動作成し、S3バケットポリシーも自動で書き込みます。先ほど作成した
oac-demo-s3-accessに切り替える手順は、後述の「オリジンのOACを差し替える」で行います。
「Next」をクリックします。
ステップ4「Enable security」では、AWS WAF によるセキュリティ保護の有効化を選択します。ここでは「セキュリティ保護を有効にしないでください」を選択し、「Next」をクリックします(WAFを有効にすると追加料金が発生します)。
ステップ5「Review and create」で設定内容を確認し、「ディストリビューションを作成」をクリックします。
作成が完了すると、「新しいディストリビューションが正常に作成されました。」というメッセージとともに詳細画面が表示されます。「ディストリビューションドメイン名」(例: d1234567890abc.cloudfront.net)をメモしておきます。


オリジンのOACを差し替える
ウィザードが自動作成したOACを、先ほど作成した oac-demo-s3-access に差し替えます。
ディストリビューションの詳細画面で「オリジン」タブを選択します。
オリジンの一覧から oac-demo-bucket-<アカウントID>.s3.ap-northeast-1.amazonaws.com の行を選択し、「編集」をクリックします。
「オリジンアクセス」で以下を確認・設定します。
- オリジンアクセス:
Origin access control settings (recommended)が選択されていること - Origin access control: ドロップダウンから
oac-demo-s3-accessを選択します


画面下部の青いメッセージにある「ポリシーをコピー」をクリックすると、このディストリビューションからのアクセスだけを許可するバケットポリシーをコピーできます(S3バケットポリシーがまだ設定されていない場合に使用します)。
「変更を保存」をクリックします。
デフォルトルートオブジェクトを設定する
ルートURL(/)へのアクセスで index.html を返すように、デフォルトルートオブジェクトを設定します。
ディストリビューションの詳細画面で「一般」タブを選択し、「設定」セクションの「編集」をクリックします。
- Default root object – optional:
index.html - Price class:
Use only North America and Europe(コスト削減のため) - その他の項目はデフォルトのままにします
「変更を保存」をクリックします。
S3バケットポリシーを確認する
ディストリビューション作成時に「Allow private S3 bucket access to CloudFront」を有効にしたため、S3バケットポリシーはCloudFrontによって自動的に設定されています。内容を確認します。
上部の検索バーに S3 と入力し、表示された「S3」を選択します。
バケット一覧から oac-demo-bucket-<アカウントID> を選択します。
「アクセス許可」タブを選択します。
「バケットポリシー」セクションに、以下のようなポリシーが設定されていることを確認します。
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::oac-demo-bucket-<アカウントID>/*",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:cloudfront::<アカウントID>:distribution/<ディストリビューションID>"
}
}
}
]
}

Principal にサービスプリンシパル cloudfront.amazonaws.com が、Condition に AWS:SourceArn によるディストリビューションの指定が入っている点を確認します。ポリシーが設定されていない場合は、「編集」から上記の内容(またはオリジン編集画面でコピーしたポリシー)を貼り付けて「変更の保存」をクリックします。
このポリシーは対象をディストリビューションのARNで絞っており、OAC のIDは含まれません。そのため、前の手順でOACを差し替えてもバケットポリシーを書き換える必要はありません。
>
なお、技術解説で示したポリシー例では条件演算子に
StringEqualsを使っていますが、コンソールが自動生成するポリシーはArnLikeを使います。ARNを完全一致で指定する場合はどちらでも同じ結果になります。



バケットポリシーはディストリビューションの ARN で絞っていて、OAC の ID は入っていないのでござる。だから OAC を差し替えても、ポリシーを書き換えずに済んだのでござるな。
動作確認:CloudFront経由のアクセス
ディストリビューションのステータスが「デプロイ済み」になったことを確認します。デプロイには数分かかります。
ブラウザで CloudFront のドメイン名にアクセスします。
https://d1234567890abc.cloudfront.net/index.htmlの内容が正常に表示されることを確認します。


動作確認:S3への直接アクセスがブロックされること
S3バケットのオブジェクトURLに直接アクセスし、アクセスが拒否されることを確認します。
ブラウザで以下のURLにアクセスします。
https://oac-demo-bucket-<アカウントID>.s3.ap-northeast-1.amazonaws.com/index.html以下のようなAccessDeniedエラーが表示されることを確認します。
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>...</RequestId>
<HostId>...</HostId>
</Error>

これにより、S3バケットへの直接アクセスがブロックされ、CloudFront経由でのみコンテンツにアクセスできることが確認できます。



OAI と OAC の機能差、とくに SSE-KMS や PUT・DELETE への対応と、バケットポリシーの Principal に何を書くかが問われる観点でござる。ディストリビューション ID を Principal に書く方式や、IAM ユーザーのキーを持たせる方式と取り違えぬよう気をつけるのでござる。
まとめ
- OACはOAIの後継であり、新規構築ではOACの使用が推奨されています
- OACはSigV4署名を使用し、すべてのAWSリージョン、SSE-KMS暗号化、PUT/DELETEなどの動的リクエストに対応しています
- OACの署名動作は3つの値(
always/never/no-override)から選択でき、S3オリジン保護にはalways(コンソールの「署名リクエスト (推奨)」)を使用します - バケットポリシーでは、サービスプリンシパル
cloudfront.amazonaws.comをPrincipalに指定し、AWS:SourceArn条件で特定のディストリビューションからのアクセスのみを許可します - CloudFrontディストリビューションIDをPrincipalに指定する方式やIAMユーザーの認証情報を使用する方式は推奨されません
- OAIからOACへの移行はダウンタイムなしで行え、移行期間中は両方のポリシーを並存させることで安全に切り替えられます
参照先
- Amazon S3 オリジンへのアクセスの制限
- オリジンアクセスコントロールを使用した Amazon Simple Storage Service オリジンへのアクセスの制限
- オリジンアクセスアイデンティティ(レガシー)からオリジンアクセスコントロールへの移行
- Amazon S3 バケットポリシーの例
- CloudFront ディストリビューションを使用して Amazon S3 バケットへのアクセスを制限する方法










