カピバラ好きなエンジニアブログ

興味ある技術とか検証した内容を赴くままに書いていきます。カピバラの可愛さこそ至高。

JSONポリシーについて簡単にまとめ

経緯

前回はポリシーについてざっくりまとめましたが、今回はポリシーを書く際に必要なJSONポリシーの要素についてまとめていきます。
前回と同じく公式からの引用が多いです。

前回記事
capybara-engineer.hatenablog.com

目次

  • JSONポリシーについて
  • 各エレメントの説明



JSONポリシーについて

まずJSONポリシーですが、大きく2つの要素で構成されます。

JSONでポリシーを作成する際は特に2つ目のステートメントが重要で、ステートメント1つに対して1つのアクセス許可を設定することができます。
さらにステートメントはアクセス許可を設定するための複数のエレメントと呼ばれるパラメータを持っており、そのエレメントを設定することで、リソースに対してのアクセス許可を設定します。

以下に主要なエレメントの詳細を記載します。

===
NotPrincipal、NotAction、NotResourceについては、今回は省略します。 名前からわかると思いますが、それぞれ許可"されない"リソース・アクション等を指定するためのエレメントです。
AWSではアクセスはデフォルトでDenyされるようになっており、そこに対して許可設定をする前提で設計されていますが、このエレメントを使用すると、指定したプリンシパルからのアクセスを拒否する(=それ以外のプリンシパルからのアクセスはすべて許可)する設定が可能となるので、不要なアクセス許可を与えかねない危険性があることを考えると、基本的には使用しないほうが良いと思います。
===

エレメント名 ステータス 説明
Version オプション 使用するポリシー言語のバージョンを指定("2012-10-17"等)
Statement 必須 ポリシーのメイン要素。アクセス許可の設定単位
Sid オプション ステートメント区別用ID
Effect 必須 Allow(許可)かDeny(拒否)を指定し、ポリシー全体でアクセスをどう制御するかを設定
Principal 一部必須 アクセスを制御するAWSアカウント、IAMユーザ、ロール等を設定。リソースベースポリシーの必須項目
Action 必須 ポリシーで制御するアクションリスト
Resporce 一部必須 アクションが適用されるリソースリスト。リソースベースポリシーでは設定しない場合、アタッチされるリソースが暗黙的に対象となる。アイデンティティベースポリシーの必須項目
Condition オプション アクセス許可を付与する状況を設定

参照先はこちら
docs.aws.amazon.com

公式ドキュメントを見ていて何気に重要だなと思ったのですが、このステートメントは1つのポリシーに複数設定できますが、AWSがポリシーを評価するときにこのステートメント全体に論理ORが適用される部分です。

AWSのアクセス制御では明示的Denyが一番強い権限として設定されるので、他のステートメントで許可設定していても別のステートメントでDenyされたらそれが適用されてしまうという状況があります。 そのため設定するときは注意が必要です。

参考までにAWSでの評価フローは以下のようになっています。

f:id:live-your-life-dd18:20191129163215p:plain

参照先はこちら
docs.aws.amazon.com

各エレメントの説明

Version

この要素はポリシーをAWSが処理する際に使用する言語構文ルールのバージョンを指定します。
ポリシーのすべての機能を使用するにはこの要素を含める必要があります。

バージョン 説明
2012-10-17 現行バージョン。ポリシー変数などの機能が使用可能
2008-10-17 旧バージョン。基本的に使用しないがVersion要素が設定されていないときはデフォルトで設定されるため注意が必要

現行バージョンのみ使用可能な機能(ポリシー変数)
docs.aws.amazon.com

記載例

"Version": "2012-10-17"



Statement

この要素は複数のエレメントを含むアクセス許可を行うステートメントを設定します。
前述した通り、ポリシーには複数のステートメントを含めることが可能ですが、設定時はこのエレメントの設定値として、ステートメントを設定していきます。

記載例

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

設定例
f:id:live-your-life-dd18:20191129171308p:plain

Sid

この要素はポリシードキュメントに与える任意の識別子を設定します。
値はステートメント配列内のステートメントごとに設定することが可能で、IAMではJSONポリシー内で固有にする必要があります。

記載例

"Sid": "1"



Effect

この要素はステートメントの結果を許可か明示的な拒否を指定します。
デフォルトではアクセスは拒否されるため、アクセスを許可するときはAllow、既に許可されているアクセスを拒否するときはDenyを設定します。

"Effect":"Allow"



Principal

この要素はリソースへのアクセス制御(Allow or Deny)を行う対象(IAMユーザ、ロール、AWSアカウント、AWSサービス等)を設定します。
Principalはアイデンティティベースのポリシーで設定することはできないため、リソースベースのポリシーかIAMロール用信頼ポリシーのみで使用可能です。

記載例 単一のアカウントを許可

"Principal": { "AWS": "arn:aws:iam::123456789012:root" }

記載例 複数のアカウントを許可

"Principal": { 
  "AWS": [
    "arn:aws:iam::123456789012:root",
    "999999999999"
  ]
}



Action

この要素は特定のサービスアクション(EC2やS3への操作)に対しての許可もしくは拒否を設定します。
設定値は、iam,ec2,sns等のアクションプレフィックスを先頭に付けて、そのあとに制御するアクションを記載します。
このアクションの部分にはワイルドカード(*)で対象サービスへのすべてのアクションに対しての制御を行うことも可能です。

記載例

"Action": [ 
  "sqs:SendMessage", 
  "sqs:ReceiveMessage", 
  "ec2:StartInstances", 
  "iam:ChangePassword", 
  "s3:*" ,
  "iam:*AccessKey*"
]



Resource

この要素はステートメントで制御するリソースを指定します。
対象のリソースはIAMユーザやS3バケット等が設定可能ですが、いずれもARN形式で記載します。
ResourceもActionと同じくワイルドカードで関連した複数のリソースに対しての制御を行うことが可能です。

ARN形式についてはこちら
docs.aws.amazon.com

記載例

"Resource": [
  "arn:aws:sqs:us-east-2:account-ID-without-hyphens:queue1",
  "Resource": "arn:aws:s3:::my_corporate_bucket/*"

ResourceはARNの一部でJSONポリシー変数を使用することができます。
例えば以下の例だと、${aws:username}と指定することで現在のユーザ名に一致する Amazon DynamoDB テーブルへのアクセスを許可します。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "dynamodb:*",
    "Resource": "arn:aws:dynamodb:us-east-2:ACCOUNT-ID-WITHOUT-HYPHENS:table/${aws:username}"
  }
}

JSONポリシーについてはこちら
docs.aws.amazon.com

Condition

この要素はポリシーを実行するタイミングの条件を指定します。
条件は指定した条件キーと値に対して、等しいや小さい等を特定の条件演算子を使用して判断します。
尚、判断はリクエストコンテキストに対して行われます。

リクエストコンテキストについてはこちら
docs.aws.amazon.com

条件演算子についてはこちら
docs.aws.amazon.com

また、条件キーはawsから始まるプレフィックスが付いているグローバル条件キーとサービスのプレフィックスが付いたサービス固有の条件キーがあります。

グローバル条件キーについてはこちら
docs.aws.amazon.com

サービス固有の条件キーについてはこちら
docs.aws.amazon.com

グローバル条件キーを使用した記載例

"Condition": {
  "DateGreaterThan" : {
     "aws:CurrentTime" : "2013-12-15T12:00:00Z"
   }
}

サービス固有条件キーを使用した記載例

"Condition": {
  "StringLike": {
    "s3:prefix": [
      "",
      "home/",
      "home/${aws:username}/"
    ]
  }
}

尚、条件は複数設定することもできます。
具体的な条件のパターンは以下の通り

パターン 条件
条件が2つ以上 AND
キーが2つ以上 AND
値が2つ以上 OR

f:id:live-your-life-dd18:20191207205353p:plain

複数の条件についてはこちら
docs.aws.amazon.com

感想及び所感

毎回AWSの公式ドキュメントを見ていて必要最低限の情報が欲しいときにドキュメントが複数あるので手間だなと思っていたので、今回はざっくり知りたいところだけまとめてみました。