LoginSignup
2
2

More than 1 year has passed since last update.

[S3]バケットポリシー書き方まとめ

Last updated at Posted at 2021-12-22

はじめに

初歩的な書き間違いで数時間ロスしたので、勉強がてら書き方を整理します。
S3のバケットポリシーを例に、jsonの要素を一つずつ確認していきます。

他のアクセス制御方法との比較

書き方の理解のためにも、少しバケットポリシーについておさらいします。
S3のユーザーアクセス権限の設定方法は以下の3種類です。

名称 概要
IAMポリシー IAMユーザ、グループ、ロールに割り当てる。要はS3のIAMポリシー。他のAWSアカウントに付与することはできないため、自アカウントに対する制御に限られる。
バケットポリシー バケット単位での柔軟な設定が可能。バケットごとに割り当てる必要がある。他のAWSアカウントに対する設定も可能。
アクセスコントロールリスト(ACL) バケット単位だけでなく、オブジェクト単位でも指定できるのが特徴。読みとり/書き込みの許可の設定ができる(拒否の設定はできない)。オブジェクトに付与されたURLについても、HTTPアクセスの許可が可能。

また、パブリックアクセス設定機能を利用することで、簡単にオブジェクトのアクセス制御を行うこともできます。

※Aのアカウントで作成したバケットの操作権限を、Bのアカウントのユーザーに付与したい場合は、IAMポリシーとバケットポリシーの両方での設定が必要です。

参考
Amazon S3 バケットに対し、オブジェクトをアップロードするアクセス権を、別の AWS アカウントのユーザーに与えるにはどうすれば良いですか?
S3で誤ったデータの公開を防ぐパブリックアクセス設定機能が追加されました

以下、バケットポリシーの要素についてまとめています。

先にざっくりまとめ

要素 概要
Version "2012-10-17"で固定(2021.12時点)。
Statement 「ここからステートメントを書きますよ~」という宣言みたいなもの。
Effect ステートメントの内容を「許可/拒否」するか。
Action 「どのAWSサービス」の「どの操作」を「許可/拒否」するか。
Resource ステートメントを「どのリソースに」適用するか。ARN形式。
Principal 「誰が」使うか。ARN形式。
Condition セキュリティ強化のためのオプション。

具体的には

こちらのAWS公式に記されている、CloudWatch LogsからS3へエクスポートするためのバケットポリシーを例に取ってみます。

{
    "Version": "2012-10-17",
    "Statement": [
      {
          "Action": "s3:GetBucketAcl",
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::my-exported-logs",
          "Principal": { "Service": "logs.us-west-2.amazonaws.com" }
      },
      {
          "Action": "s3:PutObject" ,
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::my-exported-logs/random-string/*",
          "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } },
          "Principal": { "Service": "logs.us-west-2.amazonaws.com" }
      }
    ]
}

Version

ポリシーの作成に使用される、ポリシー言語のバージョンを指定します。
ユーザーが作成したバケットポリシーのバージョニング指定ではありません。
指定できるバージョンは2種類のみ。

バージョン 概要
2012-10-17 ポリシー言語の現行バージョン。ポリシー変数などの機能を利用できるのは、このバージョンのみ。
2008-10-17 ポリシー言語の旧バージョン。非推奨。

現時点(2021.12)で、実質2012-10-17で固定です。

Statement

ポリシーの主要要素。バケットポリシーの本体なので必須です。
Statementという記述自体は、あくまでこれ以降の要素のコンテナなので、これでなにかを指定するということはありません。
以下の記法によって、複数個のステートメントを含むことができます。

"Statement": [{...},{...},{...}]

例のバケットポリシーでは、2つのステートメントを記載していますね。

以降の要素はStatementの中身となります。

Action

ポリシーで許可または拒否するアクションのリスト。

言い換えれば、「どのAWSサービス」の「どの操作」を「許可/拒否」するかの設定。
複数個指定することができます。

書き方は、

"Action(NotAction)":"サービス名(iam、ec2 sqs、sns、s3 など):アクションの名前"

"Action": "s3:GetBucketAcl"
"Action": "s3:PutObject"

これを押さえれば、例のActionの意味も分かります。
"Action": "s3:GetBucketAcl"は、「S3バケットのアクセス制御リスト(ACL)を返すこと」を許可しています。
"Action": "s3:PutObject"は、「S3バケットにオブジェクトを追加すること」を許可しています。

アクセスのリストについては、各サービスのAPIリファレンスドキュメントを参照。

とは言え、基本的なアクセス許可の設定についてはテンプレートが用意されているので、そちらを見た方が早いです。

S3の場合
Amazon S3 のアクション

Effect

必須要素。
ここで定義したステートメントの内容を、許可するか、拒否するかの指定。

AllowDenyのどちらかで許可/拒否を指定します。

例の記載順に倣ってActionの次に項目を書いていますが、Effectを先に置いた方が理解しやすいと思います。

Actionとの違いですが、

要素 概要
Action AWSサービスごとの許可/拒否の設定。
Effect ステートメントそのものの許可/拒否の設定。

例えば、
条件1:ActionでS3へのアクセスを許可(Action)。
条件2:Effectで拒否(Deny)。
結果:S3へのアクセスは拒否される。

Effect>Action
という優先順位の解釈で、とりあえず間違いはないかと。

ちなみに、
拒否(Deny)>許可(Allow)
の優先順位です。
複数個のステートメントを書く際は個別にEffectを指定するので、頭に入れておくと良いかもしれません。

Resource

ステートメントで取り扱う一連のオブジェクトの指定。
言い換えれば、ステートメントを「どのリソースに」適用するかの指定。

Resource または NotResource要素を用います。
リソースの特定には、ARN形式を用います。

ARNとは、 「Amazonリソースネーム」のことです。AWS以外にも広く用いられるJSONとは異なり、ARNはAWS独自の記法です。

ARNの基本的な書き方は、

arn:partition:service:region:account-id:resource-id

arn:aws:s3:::my-exported-logs
arn:aws:s3:::my-exported-logs/random-string/*
要素 概要
partition リソースが置かれているパーティション。"aws"でほぼ固定。中国リージョンか GovCloud (US) リージョンを利用する場合は、書き方が変わる。
service サービス名(iam、ec2 sqs、sns、s3 など)
region リソースの置かれているリージョン(ap-northeast-1など)
account-id リソースを所有しているアカウントのid。123456789012など、数字部分。
resource-id リソース識別子。リソースの名前、ID、リソースパスのいずれかを指定する。リソースパスには、ワイルドカードやアスタリスクを用いることも可能。

例の場合、my-exported-logsresource-idに当たります。

ARNの書き方を踏まえた上で、Resourceの書き方は、

"Resource(NotResource)": "arn:partition:service:region:account-id:resource-id"

ご覧の通り、ほぼARNです。

ちなみに、バケットポリシーのような"リソースベース"のポリシーの場合、Resourceはオプションです。この要素を書かなかった場合は、ポリシーがアタッチされているリソースに自動的にステートメントが適用されます。

Principal

「誰が使うか」を指定する。
いわば、Resource要素で定義した「ステートメントを適用するリソース」を、「誰が使うか」という部分です。

Principalは、ユーザーベースポリシーにはない要素です。ユーザーベースポリシーはiamユーザーやiamロールに関連づけるため、操作主体をあえてポリシーで指定する必要がないからです。
対してリソースベースポリシーは、リソースに関連づけるため、操作主体を指定する必要があります。

Resoureceと同じく、ARNを用いて記述しますが、書き方の種類が結構多いです。

参考。記述方法が分類されています。
AWS JSON ポリシーの要素: Principal

例では、サービスロールを利用した"サービスプリンシパル"という書き方をしています。ユーザーではなく、サービスに操作が許可されるというイメージです。
困ったら、取りあえず例と同様の記載をしておけば大丈夫です。

"Principal": { "Service": "サービス名.リージョン名.amazonaws.com" }

Condition

一言で言えば、オプションです。
色々できます。色々できるので、その分別途勉強した方がいいです。
取りあえずは「セキュリティ強化のための要素」程度の認識で大丈夫かと。

書き方は、

"Condition" : { "{condition-operator}" : { "{condition-key}" : "{condition-value}" }}

"Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}
名称 概要 参考
condition-operator 条件演算子 IAM JSON ポリシー要素: 条件演算子
condition-key グローバル条件キーまたはサービス固有の条件キー AWS グローバル条件コンテキストキーIAM および AWS STS の条件コンテキストキー
condition-value ポリシーの要素: 変数とタグ

例では、
「S3オブジェクトのACL(s3:x-amz-acl)」が
「バケットのオーナーに設定(bucket-owner-full-control)」されている
「場合のみ(StringEquals)」
許可するよう書いています。

例文の内容について詳しくは、
S3 のオブジェクトの所有権を使用したアップロードされたオブジェクトの所有権の管理

おわりに

間違いがあれば御指摘してくださると幸いです。

YAMLに対応してくれないかなぁ。

参考
IAM JSON ポリシー要素のリファレンス
Amazon リソースネーム (ARN)
S3のアクセスコントロールリスト(ACL)の基礎を学ぼう

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2