- AWS
CloudFront S3 OACの設定手順|バケットポリシー例と403の原因
OAC(Origin Access Control、オリジンアクセスコントロール)は、S3 バケットを非公開のまま、CloudFront からだけ読めるようにする仕組みです。 設定する場所は3つで、どれか1つが欠けると 403 になります。
| どこに | 何を設定するか | 抜けたときの症状 |
|---|---|---|
| CloudFront(OAC) | SigningBehavior: always・SigningProtocol: sigv4・OriginAccessControlOriginType: s3 |
— |
| CloudFront(オリジン) | OriginAccessControlId に OAC の ID、S3OriginConfig.OriginAccessIdentity は 空文字 "" |
S3 に署名なしで届き 403 |
| S3(バケットポリシー) | Principal は cloudfront.amazonaws.com、AWS:SourceArn にディストリビューションの ARN |
403(AccessDenied) |
| KMS(SSE-KMS のときだけ) | キーポリシーに CloudFront への kms:Decrypt など |
403 |
バケットポリシーにはディストリビューションの ID が入るので、順番は「OAC → ディストリビューション → バケットポリシー」です。
確認環境:AWS CLI 1.46.1(botocore 1.43.62)・Python 3.11(Linux)。AWS には接続せず、moto 5.2.4 のサーバーモードを相手に、この記事の CLI コマンドと JSON がパラメータの検査を通り、作成できることを確かめました。CloudFront が実際に S3 へ署名付きで取りに行く動き・403 の出方・料金・反映時間は、AWS のドキュメントに基づいて書いています(確認日 2026年10月12日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「CloudFront S3 OACの設定手順|バケットポリシー例と403の原因」
OAC と OAI の違い
OAI(Origin Access Identity)は、OAC より前からある仕組みです。AWS のドキュメントでは OAI は「legacy(従来の方式)」とされ、新しく作るなら OAC が勧められています。
| 項目 | OAC | OAI |
|---|---|---|
| 対応リージョン | すべてのリージョン(2022年12月以降のオプトインリージョンを含む) | 2023年1月以降の新しいリージョンなどは非対応 |
| SSE-KMS で暗号化したオブジェクト | 対応 | 非対応 |
PUT・DELETE など |
対応 | 非対応(PUT・POST・DELETE) |
バケットポリシーの Principal |
"Service": "cloudfront.amazonaws.com" + AWS:SourceArn 条件 |
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E…" |
| 対象を絞る単位 | ディストリビューション(ARN で指定) | OAI(複数のディストリビューションで共有できる) |
| S3 のウェブサイトエンドポイント | 使えない | 使えない |
どちらも、S3 の「静的ウェブサイトホスティング」のエンドポイント(バケット名.s3-website-リージョン.amazonaws.com)には使えません。 ドキュメントでは、ウェブサイトエンドポイントはカスタムオリジンとして設定するもので、OAC・OAI は使えないとされています。OAC で使うのは、バケット名.s3.リージョン.amazonaws.com の形の、通常の S3 エンドポイントです。
S3 のウェブサイトホスティングで公開する方法は、関連記事「S3静的ウェブサイトホスティングをAWS CLIで設定|403・404の原因」で扱っています。
AWS CLI での設定手順(JSON 一式)
ここからは、手元の moto で通したコマンドです。バケット名は rjc-site-example、リージョンは東京(ap-northeast-1)の例です。
0. 変数を決める
BUCKET=rjc-site-example
REGION=ap-northeast-1
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
1. バケットを作り、パブリックアクセスをすべてブロックする
aws s3api create-bucket --bucket "$BUCKET" \
--create-bucket-configuration LocationConstraint="$REGION"
aws s3api put-public-access-block --bucket "$BUCKET" \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
「パブリックアクセスをすべてブロック」をオンのままでも、OAC 用のバケットポリシーは設定できます。 S3 のドキュメントでは、AWS:SourceArn のような条件キーに固定の値(ワイルドカードなし)を書いたポリシーは「public ではない」と判定されるためです。ウェブサイトホスティングと違い、バケットは非公開のままです。
ドキュメントでは、OAC を使うバケットの「オブジェクト所有者」は、新しいバケットの既定値である 「バケット所有者の強制(Bucket owner enforced)」 にする、とされています。
2. OAC を作る
oac.json:
{
"Name": "rjc-site-oac",
"Description": "OAC for rjc-site bucket",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
aws cloudfront create-origin-access-control \
--origin-access-control-config file://oac.json
moto での出力です。Id の値を次の手順で使います。
{
"ETag": "LC7XR6EL6STCV",
"OriginAccessControl": {
"Id": "W5FOLBXBSYFRE",
"OriginAccessControlConfig": {
"Name": "rjc-site-oac",
"Description": "OAC for rjc-site bucket",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
}
}
名前から ID を取り出すなら、--query を使います。
OAC_ID=$(aws cloudfront list-origin-access-controls \
--query "OriginAccessControlList.Items[?Name=='rjc-site-oac'].Id" --output text)
--query の書き方は、関連記事「AWS CLI --queryの使い方|JMESPath絞り込みと出力形式」で扱っています。
SigningBehavior の3つの値(ドキュメントより):
| 値 | コンソールの表示 | 動き |
|---|---|---|
always |
署名リクエスト(推奨) | 常に署名して S3 に送る。CloudFront と S3 の間は常に HTTPS |
never |
リクエストに署名しない | 署名しない。バケットが公開されていないと S3 がエラーを返す |
no-override |
認証ヘッダーを上書きしない | 閲覧者の Authorization ヘッダーがあればそれを渡し、無いときだけ署名する |
静的サイトでは always を選びます。4つの項目(Name・SigningProtocol・SigningBehavior・OriginAccessControlOriginType)はすべて必須で、SigningProtocol を抜くと次のエラーになりました。
Parameter validation failed:
Missing required parameter in OriginAccessControlConfig: "SigningProtocol"
3. ディストリビューションを作る
dist.json(OAC_ID の部分は、あとで置き換えます):
{
"CallerReference": "rjc-site-2026-10-12",
"Comment": "rjc-site static site",
"Enabled": true,
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "s3-rjc-site-example",
"DomainName": "rjc-site-example.s3.ap-northeast-1.amazonaws.com",
"OriginAccessControlId": "OAC_ID",
"S3OriginConfig": { "OriginAccessIdentity": "" }
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "s3-rjc-site-example",
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
"Compress": true,
"AllowedMethods": {
"Quantity": 2,
"Items": ["GET", "HEAD"],
"CachedMethods": { "Quantity": 2, "Items": ["GET", "HEAD"] }
}
},
"PriceClass": "PriceClass_All"
}
sed "s/OAC_ID/$OAC_ID/" dist.json > dist-filled.json
aws cloudfront create-distribution --distribution-config file://dist-filled.json \
--query "Distribution.{Id:Id,ARN:ARN,Domain:DomainName,Status:Status}"
moto での出力です。ARN をバケットポリシーに書きます。
{
"Id": "VJTA2WK7GGYSA",
"ARN": "arn:aws:cloudfront::123456789012:distribution/VJTA2WK7GGYSA",
"Domain": "e942sexxd24c0.cloudfront.net",
"Status": "InProgress"
}
| 項目 | 意味 | 注意点 |
|---|---|---|
CallerReference |
二重作成を防ぐための一意な文字列 | 同じ値で2回作ると DistributionAlreadyExists |
DomainName |
リージョン付きの S3 エンドポイント | s3-website の形は OAC では使えない |
OriginAccessControlId |
手順2の OAC の ID | ここが空だと署名されない |
S3OriginConfig.OriginAccessIdentity |
OAI の指定 | OAC のときも "" を書く(省略不可) |
CachePolicyId |
マネージドの CachingOptimized | 既定の TTL は 86,400 秒(24時間) |
DefaultRootObject |
/ に来たときに返すファイル |
先頭に / を付けない |
S3OriginConfig の OriginAccessIdentity は、OAC を使うときも空文字で書く必要があります。 省略すると、AWS に送る前に CLI が止まりました。
Parameter validation failed:
Missing required parameter in DistributionConfig.Origins.Items[0].S3OriginConfig: "OriginAccessIdentity"
CallerReference を使い回したときは、次のエラーでした。
An error occurred (DistributionAlreadyExists) when calling the CreateDistribution operation: The caller reference that you are using to create a distribution is associated with another distribution. Already exists: VJTA2WK7GGYSA
ドキュメントでは、ディストリビューションを消すときは S3 バケットより先に消すか、オリジンのドメイン名にリージョンを含めるよう案内されています。上の DomainName はリージョン付きの形です。
4. バケットポリシーを設定する(AWS:SourceArn 条件)
DIST_ID=VJTA2WK7GGYSA # 手順3の Id
cat > bucket-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipalReadOnly",
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::${BUCKET}/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::${ACCOUNT_ID}:distribution/${DIST_ID}"
}
}
}
]
}
JSON
aws s3api put-bucket-policy --bucket "$BUCKET" --policy file://bucket-policy.json
AWS:SourceArn の形は arn:aws:cloudfront::アカウントID:distribution/ディストリビューションID です。 CloudFront はグローバルなサービスなので、ARN のリージョンの部分は空(::)になります。この条件があるので、同じアカウントの別のディストリビューションからは読めません。
| ポリシーの書き方 | 意味 |
|---|---|
"Resource": "arn:aws:s3:::バケット名/*" |
バケットの中のオブジェクト(GetObject はこちら) |
"Resource": "arn:aws:s3:::バケット名" |
バケットそのもの(ListBucket はこちら) |
"Action": ["s3:GetObject", "s3:PutObject"] |
CloudFront 経由のアップロードも許す(ドキュメントの読み書き用の例) |
存在しないパスに 404 を返したいときは、s3:ListBucket も許します。 S3 のドキュメントでは、オブジェクトが無いとき、s3:ListBucket の権限があれば 404、無ければ 403 を返すとされています。
{
"Sid": "AllowCloudFrontListBucket",
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::rjc-site-example",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/VJTA2WK7GGYSA"
}
}
}
バケットポリシーの書き方全般は、関連記事「S3バケットポリシーの書き方と例 IP制限・Condition早見表」で扱っています。
5. ファイルを置き、反映を待つ
aws s3 cp index.html "s3://$BUCKET/index.html" \
--content-type text/html --cache-control "max-age=300"
aws cloudfront wait distribution-deployed --id "$DIST_ID"
curl -I "https://$(aws cloudfront get-distribution --id "$DIST_ID" \
--query Distribution.DomainName --output text)/"
wait distribution-deployed は、状態が InProgress から Deployed になるまで待つコマンドです。まとめてアップロードするときは、関連記事「aws s3 syncの使い方 cpとの違いとexclude・delete早見表」で扱っています。
既存のディストリビューションに OAC を付ける
ドキュメントの手順は、設定を取り出して書き換え、update-distribution で戻す形です。
aws cloudfront get-distribution-config --id "$DIST_ID" --output yaml > dist-config.yaml
# 編集する:
# - Origins の OriginAccessControlId に OAC の ID を入れる
# - OriginAccessIdentity の値を消す(空にする)
# - ETag というキーの名前を IfMatch に変える(値はそのまま)
aws cloudfront update-distribution --id "$DIST_ID" --cli-input-yaml file://dist-config.yaml
--cli-input-yaml は AWS CLI v2 のオプションです。手元の v1(1.46.1)の update-distribution help には --cli-input-json しかありませんでした。v1 では、get-distribution-config の JSON から DistributionConfig の部分だけを取り出し、--distribution-config file://… と --if-match ETagの値 で渡します。
OAI から移行するときのバケットポリシー
OAI と OAC の両方を許す文を一時的に並べておけば、切り替えの途中でも読めなくなりません。 ドキュメントの手順は次の3段階です。
- バケットポリシーに、OAC 用と OAI 用の2つの文を並べる
- ディストリビューションを OAC に切り替える
- 反映(Deployed)を待ってから、OAI 用の文を消す
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipalReadOnly",
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::rjc-site-example/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/VJTA2WK7GGYSA"
}
}
},
{
"Sid": "AllowLegacyOAIReadOnly",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E2EXAMPLEOAI"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::rjc-site-example/*"
}
]
}
OAI の ID は、aws cloudfront list-cloud-front-origin-access-identities の Id で確かめられます。
デフォルトルートオブジェクトとサブディレクトリの index.html
DefaultRootObject が効くのは、ルート(/)だけです。 ドキュメントには「サブディレクトリへのリクエストには、デフォルトルートオブジェクトを返さない」とあります。
| リクエスト | S3 に取りに行くキー | 結果(ListBucket なし) |
|---|---|---|
/ |
index.html(DefaultRootObject) |
表示される |
/about/ |
about/(そのまま) |
403 |
/about |
about |
403 |
/about/index.html |
about/index.html |
表示される |
S3 のウェブサイトホスティングは、サブディレクトリでも index ドキュメントを返します。OAC の REST エンドポイントにはその機能が無いので、ウェブサイトホスティングから移すと、ここで 403 になります。
直し方は、CloudFront Functions(エッジで動く軽い JavaScript)で、URL の末尾に index.html を付けることです。 次の関数は、AWS のドキュメントのコード例(JavaScript ランタイム 2.0)です。
async function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
関数の中身を Node.js 22 で呼び出したときの結果です。
| リクエストの URI | 書き換え後 |
|---|---|
/ |
/index.html |
/about/ |
/about/index.html |
/about |
/about/index.html |
/blog/2026/post |
/blog/2026/post/index.html |
/css/site.css |
/css/site.css(そのまま) |
. を含むパスは書き換えません。 /docs/v1.2 のように、ディレクトリ名にドットがあるサイトでは、条件を変える必要があります。
関数の作成から関連付けまでの CLI です。create-function は moto で通り、publish-function 以降はドキュメントの手順です。
aws cloudfront create-function --name rjc-index-rewrite \
--function-config Comment="append index.html",Runtime=cloudfront-js-2.0 \
--function-code fileb://index-rewrite.js
ETAG=$(aws cloudfront describe-function --name rjc-index-rewrite --query ETag --output text)
aws cloudfront publish-function --name rjc-index-rewrite --if-match "$ETAG"
ディストリビューションの DefaultCacheBehavior に、次のように関連付けます(ビューワーリクエストで動かす)。
"FunctionAssociations": {
"Quantity": 1,
"Items": [
{
"EventType": "viewer-request",
"FunctionARN": "arn:aws:cloudfront::123456789012:function/rjc-index-rewrite"
}
]
}
SPA(React・Vue など)のとき
ルーティングを JavaScript で行う SPA では、どのパスでも /index.html を返す設定が使われます。CustomErrorResponses で、403 を /index.html・ステータス 200 に置き換える形です(moto で作成できた設定)。
"CustomErrorResponses": {
"Quantity": 1,
"Items": [
{ "ErrorCode": 403, "ResponsePagePath": "/index.html", "ResponseCode": "200", "ErrorCachingMinTTL": 10 }
]
}
この設定では、本当に無いファイルや権限の誤りも 200 で返るので、原因が見えにくくなります。 s3:ListBucket を許して 404 にしている場合は、ErrorCode を 404 にします。
SSE-KMS で暗号化したバケットのキーポリシー
バケットを SSE-KMS(自分の KMS キーでの暗号化)にしている場合、バケットポリシーだけでは読めません。 KMS キーのキーポリシーに、CloudFront を許す文を足します。次の文はドキュメントの例で、moto では put-key-policy で設定できました。
{
"Sid": "AllowCloudFrontServicePrincipalSSE-KMS",
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": ["kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKey*"],
"Resource": "*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/VJTA2WK7GGYSA"
}
}
}
aws kms get-key-policy --key-id "$KEY_ID" --policy-name default \
--query Policy --output text > key-policy.json
# key-policy.json の Statement に上の文を足す(既存の文は消さない)
aws kms put-key-policy --key-id "$KEY_ID" --policy-name default --policy file://key-policy.json
既存の文(アカウントの root に kms:* を許す文など)を消すと、キーを管理できなくなるおそれがあります。 文は足すだけにします。
| バケットの暗号化 | キーポリシーの変更 |
|---|---|
SSE-S3(AES256、既定) |
要らない |
SSE-KMS(AWS マネージドキー aws/s3) |
AWS マネージドキーはキーポリシーを編集できないため、上の文を足せない。カスタマーマネージドキーを使う |
| SSE-KMS(カスタマーマネージドキー) | 上の文を足す |
SSE-S3 と SSE-KMS の違いは、関連記事「S3暗号化の設定|SSE-S3とSSE-KMSの違いとCLIでの確認方法」で扱っています。キーポリシーの扱いは、関連記事「AWS KMSの使い方|CLIとboto3で暗号化・復号・データキー」で扱っています。
403・404 の原因表
| 症状 | 原因 | 確かめ方・直し方 |
|---|---|---|
| どのパスも 403 | バケットポリシーが無い/AWS:SourceArn のディストリビューション ID かアカウント ID が違う |
aws s3api get-bucket-policy と get-distribution --query Distribution.ARN を見比べる |
| どのパスも 403 | オリジンに OAC が付いていない | get-distribution-config の OriginAccessControlId を見る |
| どのパスも 403 | オリジンがウェブサイトエンドポイント(s3-website) |
DomainName を バケット名.s3.リージョン.amazonaws.com に変える |
| どのパスも 403 | SSE-KMS のキーポリシーに CloudFront が無い | 上のキーポリシーの文を足す |
/ だけ 403 |
DefaultRootObject が未設定、または /index.html と先頭に / を付けた |
index.html と書く(ドキュメントにも 403 の原因とある) |
/about/ が 403 |
サブディレクトリには DefaultRootObject が効かない | CloudFront Functions で index.html を付ける |
| 一部のファイルだけ 403 | ファイルが無い(ListBucket が無いので 404 でなく 403) |
aws s3 ls s3://バケット名/パス で、キーの綴り・大文字小文字を見る |
| 一部のファイルだけ 403 | 別アカウントがアップロードし、ACL で所有者が違う | オブジェクト所有者を「バケット所有者の強制」にする |
| 404 が 200 で index.html になる | CustomErrorResponses で置き換えている |
意図どおりか確かめる |
| 設定を変えたのに 403 のまま | 反映前、またはエラー応答がキャッシュされている | wait distribution-deployed、エラーのキャッシュ時間(ErrorCachingMinTTL)を見る |
S3 に直接アクセスして 403 になるのは、OAC が正しく働いている状態です。 確かめるのは CloudFront のドメイン(xxxx.cloudfront.net)経由のほうです。
キャッシュが更新されない:invalidation と TTL
S3 のファイルを上書きしても、CloudFront のエッジに残ったキャッシュは、TTL(キャッシュの有効期間)が切れるまで返り続けます。 マネージドの CachingOptimized は、オリジンが Cache-Control を返さないとき 24時間(86,400秒)キャッシュします。
| 原因 | 直し方 |
|---|---|
| エッジのキャッシュが残っている | create-invalidation で消す |
Cache-Control を付けずにアップロードした |
aws s3 cp --cache-control "max-age=300" などで付ける |
| CachingOptimized の最小 TTL(1秒)がある | no-cache を付けても最低1秒はキャッシュされる |
| ブラウザのキャッシュ | 開発者ツールでキャッシュを無効にして確かめる |
| ファイル名が同じ | app.3f9a1c.js のように中身ごとに名前を変える(ドキュメントで推奨) |
aws cloudfront create-invalidation --distribution-id "$DIST_ID" \
--paths "/index.html" "/css/*"
moto での出力です。
{
"Id": "FVWA9BIUW4SRC",
"Status": "COMPLETED",
"Paths": {
"Quantity": 2,
"Items": [
"/index.html",
"/css/*"
]
}
}
実際の AWS では、作成直後は InProgress で、aws cloudfront wait invalidation-completed --distribution-id … --id … で完了を待てます。
invalidation のパスのルール(ドキュメントより):
| ルール | 例 |
|---|---|
CLI・API では先頭に / を付ける |
/index.html |
* は末尾だけワイルドカード。途中の * は文字として扱われる |
/css/*、全部なら /* |
CLI ではパスを " で囲む |
"/*" |
| 大文字と小文字を区別する | /Image.jpg と /image.jpg は別 |
/about/ と /about は別のパス |
両方を指定する |
料金:毎月 1,000 パスまで無料。* を含むパスは何件消しても1パス |
/* は1パスとして数える |
/index.html だけを消しても、/ のキャッシュは別に残ります。 DefaultRootObject のページを更新したら、/ と /index.html の両方を指定するか、/* を使います。
よくある質問
Q. OAC は CloudFront のどのリージョンで作りますか。
A. CloudFront はグローバルなサービスなので、OAC もディストリビューションもリージョンを選びません。S3 バケットのリージョンは、オリジンの DomainName(バケット名.s3.ap-northeast-1.amazonaws.com)に入ります。
Q. 1つの OAC を複数のディストリビューションで使えますか。
A. 使えます。バケットポリシーの AWS:SourceArn に、許したいディストリビューションの ARN を並べます(StringEquals の値を配列にする)。
Q. CloudFront 経由でアップロード(PUT)できますか。
A. OAC は PUT・DELETE に対応しています。ドキュメントには、バケットポリシーの Action を ["s3:GetObject", "s3:PutObject"] にした読み書き用の例があります。キャッシュ動作の AllowedMethods にも、PUT などを含める必要があります。
Q. 独自ドメインを使うには。
A. us-east-1(バージニア北部)の ACM で証明書を発行し、ディストリビューションの Aliases と ViewerCertificate に設定します。ドキュメントでは、CloudFront で使う ACM の証明書は us-east-1 で作るとされています。
まとめ
- OAC は 「OAC を作る → オリジンに付ける → バケットポリシー」 の3点セット。順番は OAC → ディストリビューション → バケットポリシー
- バケットポリシーは
Principal: cloudfront.amazonaws.com+AWS:SourceArn(ディストリビューションの ARN)。パブリックアクセスのブロックはオンのまま - CLI では
S3OriginConfig.OriginAccessIdentityに""を書く。省略するとパラメータ検査で止まる - DefaultRootObject はルートだけ。サブディレクトリは CloudFront Functions で
index.htmlを付ける - SSE-KMS(カスタマーマネージドキー)はキーポリシーにも CloudFront を足す
- 無いファイルは
ListBucketが無いと 403。更新が出ないときは/と/index.htmlの両方を invalidation
参考・出典
確認日はいずれも 2026年10月12日です。
- Amazon CloudFront デベロッパーガイド「Restrict access to an Amazon S3 origin」:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
- Amazon CloudFront デベロッパーガイド「Specify a default root object」:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html
- Amazon CloudFront デベロッパーガイド「Add index.html to request URLs that don't include a file name」(CloudFront Functions のコード例):https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/example_cloudfront_functions_url_rewrite_single_page_apps_section.html
- Amazon CloudFront デベロッパーガイド「Use managed cache policies」:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html
- Amazon CloudFront デベロッパーガイド「What you need to know when invalidating files」:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/invalidation-specifying-objects.html
- Amazon CloudFront デベロッパーガイド「Pay for file invalidation」:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PayingForInvalidation.html
- Amazon S3 API リファレンス「GetObject」(ListBucket の有無と 403・404):https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
- Amazon S3 ユーザーガイド「Blocking public access to your Amazon S3 storage」(The meaning of "public"):https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「CloudFront S3 OACの設定手順|バケットポリシー例と403の原因」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。