テクニカルインストラクターと学ぶ AWS KMS のキーポリシー
Author : 杉本 圭太
テクニカルインストラクターの杉本圭太です !
最近読んで面白かった漫画は「ありす、宇宙までも」です。
今回はデータの暗号化やデジタル署名などで役立つ AWS Key Management Service (AWS KMS) のキーポリシーの基本を学んでいきます !
キーポリシーはリソースベースのポリシーの一種ですが、みなさんはリソースベースのポリシーの動作がリソースの種類ごとに異なる場合があることをご存知でしょうか ? 例えば Amazon S3 のバケットポリシーの使い方を理解していても、キーポリシーを同じように使ったら想定通りにアクセス許可ができないかもしれません。
AWS KMS は Amazon S3、Amazon EBS、Amazon RDS、Amazon DynamoDB などと併せて使用することも多いので、セキュリティ担当者ではなくても最低限の知識は持っておきたいですよね ! そこでトレーニングでもよく質問を受けるキーポリシーの混乱しやすい点を整理して、適切に使えるようにしていきましょう ( ・∀・)b
ということでいきなりですがクイズです ! これに自信を持って回答できない方は今回の記事で キーポリシーの基本を学んでみてください φ(•ᴗ•๑)

目次
1. クイズの正解
正解は・・・
(1) GetObject → 許可される
(2) Decrypt → 拒否される
でした ! それでは順に解説していきます。
2. AWS KMS の概要
AWS KMS では、KMS キーというリソースを使用してデータの暗号化 (Encrypt) や 復号 (Decrypt) などの機能が利用できます。KMS キーには AWS 利用者が作成する「カスタマー管理のキー (カスタマーマネージドキー)」と呼ばれる種類があり、キーポリシーを設定してキーの使用者や操作を制御できます。KMS キーの種類には他にも「AWS 管理のキー (AWS マネージドキー)」という、キーポリシーなどの設定ができないものもあります。
リソースベースのポリシーのおさらい
ドキュメントの IAM と連携するサービス に一覧があるのですが、いくつかのサービスではリソースベースのポリシーが利用できます。リソースベースのポリシーを使用することでアイデンティティベースのポリシー側に Allow を記載しなくても、特定の IAM ロールや AWS サービスなどからのリクエストを許可できます。
つまりリソースベースのポリシーを持つリソースへのリクエストが許可されるか拒否されるかは、アイデンティティベースのポリシーとリソースベースのポリシーの記載内容を総合的に判断して決定されます。端的に言うとどちらかに対象の操作の Deny がある、もしくは Allow が明示的にない場合はリクエストが拒否されます。そして明示的な Allow があればリクエストが許可されるのですが、リソースベースのポリシーによって明示的な許可の記述方法に違いがあります。
キーポリシーの特徴
リソースベースのポリシーの中で KMS キーに設定できるものがキーポリシーです。ここでドキュメントに記載されているキーポリシーの特徴を 2 つ挙げます。
- Every KMS key has a key policy. (要約: 全ての KMS キーには 1 つキーポリシーが必要です)
- リソースベースのポリシーを使用できるけれど設定しなくても良いリソース (S3 バケットポリシーや Amazon SQS ポリシーなど) とは異なります
- Unlike other AWS resource policies, an AWS KMS key policy does not automatically give permission to the account or any of its identities. (要約: 他の AWS リソースのポリシーとは異なり、キーポリシーは自動的にアカウントやアイデンティティに権限を与えません)
- これはキーポリシー側に Principal を指定しておかないとルートユーザーや KMS キーへの Action を Allow にしているポリシーを持っている IAM ロールでも許可されませんよという意味で、この記事で詳細を解説していきます
3. 押さえておきたい 4 つのリクエストパターン
キーポリシーを理解するために、IAM ロール側のポリシーと組み合わせてどういう状態であればリクエストが許可されるのかを整理するため 4 つのパターンを用意しました !
ここからいくつか図を載せていますが、概略図なので以下の条件であることはご了承ください。
- ポリシーの内容は省略しており Statement の中身だけを記載しています
- 評価に影響するのは図に記載されているものだけで、AWS KMS のグラント やアクセス許可の境界 (Permissions boundary) 、サービスコントロールポリシー (SCPs) などは使用していません
パターン①
まずはリソースベースのポリシーにのみ、対象の IAM ロールからの Action を許可しているパターンです。
今回の例だと以下の条件です。
- IAM ロール (Dev) のポリシーに KMS キーへの Action は Allow も Deny も記載されていない
- AWS KMS のキーポリシーに、IAM ロール (Dev) の ARN を Principal とした Allow を記載している

このパターンでは IAM ロール (Dev) からの Decrypt リクエストは許可されます。
理由は Deny がどちらにもなくリソースベース側に Allow が記載されているためで、これは S3 のバケットポリシーなど他の多くのリソースベースのポリシーも同じ挙動です。
パターン②
次は IAM ロールのポリシーにのみ AWS KMS の Action を許可しているパターンです。
今回の例だと以下の条件です。
- IAM ロール (Dev) のポリシーに KMS キーへの Action を Allow と記載している
- KMS のキーポリシーには、IAM ロール (Sec) の ARN を Principal とした Allow のみ記載されている (IAM ロール (Dev) に関しては Allow も Deny も記載はない)

このパターンは冒頭のクイズとして出題したものですが、IAM ロール (Dev) からの Decrypt リクエストは許可されません。
このように IAM ロール側にだけ Allow が記載されていれば、S3 のバケットポリシーなど他の多くのリソースベースのポリシーを持つリソースへのリクエストは許可されます。これが キーポリシーを使う場合に注意が必要な部分です。
AWS KMS の場合に許可されない理由は「キーポリシー側で Principal に IAM ロールを記載」か、次のパターン③のように「キーポリシー側で Principal に AWS アカウントを記載」しない限りは IAM ロール側のポリシーで KMS キーに対するリクエストが許可されない仕様になっているからです。
S3 の場合であればバケットポリシーで IAM ロール (Dev) に対して明示的な許可がなくても、明示的な拒否がない限りは IAM ロール (Dev) 側のポリシーに対象のリソースへの Action が許可されていればリクエストは成功します。
参考:
https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html
No AWS principal, including the account root user or key creator, has any permissions to a KMS key unless they are explicitly allowed, and never denied, in a key policy, IAM policy, or grant.
Unless the key policy explicitly allows it, you cannot use IAM policies to allow access to a KMS key. Without permission from the key policy, IAM policies that allow permissions have no effect.
パターン③
今度はパターン②からリソースベースのポリシーの Principal を変更し、AWS アカウントを示す ARN (arn:aws:iam::<AWS ACCOUNT ID>:root) に対して許可を与えています。
今回の例だと以下の条件です。
- IAM ロール (Dev) のポリシーに KMS キーへの Action を Allow と記載している
- KMS のキーポリシーには、AWS アカウント (111122223333) を Principal とした Allow のみ記載されている (IAM ロール (Dev) に関しては Allow も Deny も記載はない)
- キーポリシーに限らず AWS サービスのポリシー内で使用する arn:aws:iam::111122223333:root は、AWS アカウントのルートユーザーのことではなく AWS アカウント自体という意味を持つ ARN ですのでご注意ください

このパターンでは IAM ロール (Dev) からの Decrypt リクエストは許可されます。
これがキーポリシーを扱う上で混乱しやすい点の 1 つだと思います。パターン①と②では、AWS KMS を扱う場合はキーポリシー側で Principal を明示して Allow を書かないと IAM ロール側のポリシーに Allow があってもリクエストが許可されないことを確認しました。
しかし IAM ロール側のポリシーで KMS キーに対する Action へ Allow を記述しても意味がない訳ではありません。というのもキーポリシーの Principal で AWS アカウントを表す ARN (arn:aws:iam::<AWS ACCOUNT ID>:root) を指定しておけば、その AWS アカウント内の IAM ロール側にある KMS キーに対する Action の Allow が効果を発揮するという仕組みになっています。つまり合わせ技一本といった感じでしょうか !
S3 の場合であればパターン②で見たように、わざわざリソースベースのポリシー側に AWS アカウントに対する Allow を記載しなくても、アイデンティティベース側のポリシーに Allow があれば (他で Deny がない限り) リクエストは成功します。多くのリソースベースのポリシーはアイデンティティベース側のポリシーのみで成立するのですが、キーポリシーは違うということを覚えておきましょう。
Without this permission, IAM policies that allow access to the key are ineffective
When the principal in a key policy statement is the account principal, the policy statement doesn't give any IAM principal permission to use the KMS key. Instead, it allows the account to use IAM policies to delegate the permissions specified in the policy statement.
When you specify an AWS account, you can use the account ARN (arn:aws:iam::account-ID:root), or a shortened form that consists of the "AWS": prefix followed by the account ID.
For example, given an account ID of 123456789012, you can use either of the following methods to specify that account in the Principal element:
"Principal": { "AWS": "arn:aws:iam::123456789012:root" }
"Principal": { "AWS": "123456789012" }
パターン④
最後は キーポリシーはパターン③と同じですが、IAM ロール (Dev) のポリシーで KMS キーに対する明示的な許可をしていないとどうなるかを確認しておきましょう。
今回の例だと以下の条件です。
- IAM ロール (Dev) のポリシーに KMS キーへの Action は Allow も Deny も記載されていない
- KMS のキーポリシーには、AWS アカウント (111122223333) を Principal とした Allow のみ記載されている (IAM ロール (Dev) に関しては Allow も Deny も記載はない)

このパターンでは IAM ロール (Dev) からの Decrypt リクエストは許可されません。
パターン③の時に合わせ技一本ですと書きましたが、キーポリシーに AWS アカウントに対する Allow の記述があるだけでは IAM ロール側で KMS キーに対する Allow がなければリクエストは許可されないということです。
キーポリシーに AWS アカウントに対する Allow の記述があるというのは、それだけでは IAM ロールへの許可にはならないけどアイデンティティベースのポリシー次第で許可させるかを決められる状態だと考えていただくと分かりやすいかもしれません。つまり キーポリシーで AWS アカウントに対して “kms:*” の Action を Allow と記述していれば、S3 バケットポリシーなど多くのリソースベースのポリシーが空の状態と同じと考えられますね !
4. AWS アカウントのルートユーザーと AWS KMS のキーポリシー
パターン③と④で登場した AWS アカウントを表す ARN (arn:aws:iam::<AWS ACCOUNT ID>:root) は「AWS アカウントのルートユーザー自体を表すものではない」とお伝えしましたが、キーポリシーの場合は arn:aws:iam::<AWS ACCOUNT ID>:root を Principal として明示的に Action の許可を与えておかないとルートユーザーを使用しても KMS キーの操作はできないというのも注意が必要な点です。
つまりキーポリシーに IAM ロールの ARN を指定した Allow しか記述していない場合は、ルートユーザーを使っても操作ができません。

5. デフォルトのキーポリシー
KMS キーには必ず 1 つのキーポリシーが必要になるため、KMS キー作成時にキーポリシーを指定しなければ デフォルトのキーポリシー が作成されます。KMS キーを作ったことがある方は、よくわからないまま AWS アカウントに対して全ての Action を Allow するキーポリシーが作成されて「これはどういう意味を持つの ?」「そもそも必要なの ?」と感じたことがあるかもしれません。私も初めての時は「何だこれは ?」と思って必死にドキュメントを調べました 😉
デフォルトキーポリシーは AWS CLI や AWS SDK などを使用する場合だと以下の Statement が設定されています。マネジメントコンソールを使用する場合は以下の Statement に、オプションで管理者用とユーザー用の Statement も加えられます。
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
}
ここまでの内容を学んできたことにより、デフォルトのキーポリシーがどんな役割を持つか理解できるようになったのではないでしょうか ? そうです、これは同じアカウント内であればアイデンティティベースのポリシーに Allow を記述している IAM ロールもしくはルートユーザーからこの KMS キーの操作ができる状態ということですね !
ドキュメントにも記載がありますが必要に応じてデフォルトのキーポリシーは編集していただいて大丈夫ですが、AWS アカウントの権限を削除してしまうことでいざという時にルートユーザーから KMS キーを操作できなくなる点はご注意ください。
参考:
https://docs.aws.amazon.com/kms/latest/developerguide/control-access.html
We recommend that you edit the default key policy to align with your organization’s requirements for least-privilege permissions.
https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html
It reduces the risk of the key becoming unmanageable by giving access control permission to the account administrators, including the account root user, which cannot be deleted.
For example, suppose you create a key policy that gives only one user access to the KMS key. If you then delete that user, the key becomes unmanageable and you must contact AWS Support to regain access to the KMS key.
6. おまけ: AWS マネージドキーについて
詳細は AWS KMS keys のドキュメント に記載されていますが、AWS マネージドキーはキーポリシーやローテーションの設定を AWS 利用者が変更はできないけれど KMS キーの保持にはコストがかからないで使用できます。
こちらは手軽に AWS サービスと連携したサーバーサイド暗号化ができるメリットがありますが、キーポリシーを変更できないためクロスアカウントアクセスはできない点は注意が必要です。後からデータを暗号化している KMS キーを変更するのは大変になる場合があるので、AWS マネージドキーを使用する場合は今後クロスアカウントアクセスする予定があるかどうかは検討しておきましょう !
参考:
https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html
You cannot share resources encrypted under an AWS managed key with other accounts.
7. まとめ
最後に今回学んだことを確認しましょう !
- リソースベースのポリシーの使い方はリソースの種類ごとに異なる場合がある
- 多くのリソースベースのポリシーとは異なり、AWS KMS ではキーポリシー側に Principal を指定して Allow を記述しないと IAM ロールを使用して KMS キーの操作ができない
- つまりキーポリシーで明示的に許可されていない場合、IAM ロール側のポリシーに KMS キーに対する Action を Allow しているだけではリクエストは許可されない
- ただしキーポリシーの Principal で AWS アカウントを指定した Allow があれば、IAM ロール側のポリシーとの組み合わせることでリクエストを許可できる
このようにテクニカルインストラクターは、自学だけではつまずきやすい部分などを含め、みなさんにより AWS を理解してもらいやすくなる工夫を日々行いながら クラスルームトレーニング を提供しております !
質問もリアルタイムでできるため分からない部分はとことんお付き合いしますし、ほとんどのコースには演習の時間も多くあるため学んだ内容を AWS 環境で実践できます !
AWS のトレーニングについてもっと知りたい方は、以下の連載記事も参考にどうぞ。
これまで自分で勉強してきたけど AWS を体系的に学ぶことでもっと詳しくなって業務で活用したい ! という方はぜひ AWS のトレーニングを受講してみてください !
筆者プロフィール

杉本 圭太
アマゾン ウェブ サービス ジャパン合同会社
トレーニングサービス本部 テクニカルインストラクター
テクニカルインストラクターとして、知識をつけることが目的ではなく実際に業務で活用できる力を得ることを目指したトレーニングを提供しています。自分自身が新しいことを知るのが好きなので、「AWS を知るのは面白い ! もっと学んでみよう !」と多くの方に感じてもらえる工夫を常に考えながら活動しています。
AWS を無料でお試しいただけます