IAM Policy Statementにおける NotAction / NotResource とは?

IAM

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

よく訓練されたアップル信者、都元です。以前IAMによるAWS権限管理 – IAMポリシーの記述と評価論理というエントリにて、IAMポリシーの書き方を解説しました。

先のエントリで、ポリシーステートメントはEffect, Action, Resourceから成る、という説明をしました。これはこれで基本的に間違い無いのですが、Actionの代わりにNotAction、Resourceの代わりにNotResourceというキーが利用できる、ということを本日はご紹介しようと思います。

Allow-NotActionとDeny-Actionの違い

ステートメントにおけるNot〜を理解するにあたって理解しなければならないのはこのテーマに尽きます。下記2つのポリシーはどう違うのでしょうか。

Allow-NotActionパターン

{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "NotAction": "iam:*",
      "Resource": "*"
    }
  ]
}

Deny-Actionパターン

{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": "iam:*",
      "Resource": "*"
    }
  ]
}

このポリシーだけを適用した場合は許可される権限に違いは無い、というのが答えになります。しかし多くの場合、1つのIAMグループ・ユーザ等には複数のポリシーが付与されます。

例えばAllow-NotActionパターンのポリシーを適用したユーザAと、Deny-Actionパターンのポリシーを適用したユーザBがいたとします。

これらA, Bが属するグループに下記ポリシーを追加付与した場合、どうなるでしょうか。これは「自分自身のパスワードを変更できる」という許可ポリシーです。

{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iam:ChangePassword",
      "Resource": "arn:aws:iam::000000000000:user/${aws:username}"
    }
  ]
}

この時、Aさんは自分のパスワードを変更できるようになりますが、Bさんは依然パスワード変更を弾かれてしまいます。IAMによるAWS権限管理 – IAMポリシーの記述と評価論理でも解説した通り、Denyは絶対です。従って、別のポリシーでIAMの何らかのアクションを許可したとしても、とにかくDenyが効いてくるため、このような差異が出てくるわけです。

NotActionの読み替え

ポリシー記述の際に「Allow-NotActionで書こうか、Deny-Actionで書こうか」というのは迷うことがあります。前述の通り「Denyは絶対的」という原則を理解していればほとんどの場合は問題ないと思いますが、NotActionがどのような効果をもたらすのかを完全に理解しなければ、色々不安になってしまうことでしょう。

{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "NotAction": "iam:*",
      "Resource": "*"
    }
  ]
}

従って、前述のポリシー(上記)は、意味的には下記のように理解する、とおぼえておくと良いでしょう。

{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [ ..., 【iam:*にあてはまらない全てのアクション】, ... ],
      "Resource": "*"
    }
  ]
}

最後に。ResourceについてはNotResourceというキーも利用できますが、全く同じノリです。指定したリソース以外全てに対するポリシーを記述する際に利用するものです。