#はじめに
初歩的な書き間違いで数時間ロスしたので、勉強がてら書き方を整理します。
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
必須要素。
ここで定義したステートメントの内容を、許可するか、拒否するかの指定。
Allow
と Deny
のどちらかで許可/拒否を指定します。
例の記載順に倣って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-logs
がresource-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)の基礎を学ぼう