KMSの権限周りが非常にややこしいので記事にします。AWS Certified Security Specialty、通称SCSを受験した際もここが一番の難関だった記憶があります。
キーポリシーとは
まず、AWSの権限管理の方法は主に2通りあります。
1つはIAMポリシーをIAMグループ、IAMユーザー、IAMロールにIAMポリシーをアタッチして権限を与えるアイデンティティベースで管理する方法です。
そしてもう1つが、S3バケットやSQSキューなどにリソースポリシーをアタッチして権限を与えるリソースベースで管理する方法です。https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_identity-vs-resource.html
キーポリシーとは、AWS KMS keyのためのリソースポリシーのことを言います。
他のリソースベースのポリシーとの違い
キーポリシーは必ず設定する必要があります。一方、他のリソースポリシーが利用できるサービスではリソースポリシーはオプションとなっています。
というのも、KMSはキーポリシーで許可されていなければrootユーザーであってもKMSにアクセスする権限がありません!言い換えると、キーポリシーが設定されていないとどう足掻いてもKMSを利用できないことになってしまいます。
KMSではデフォルトのキーポリシーというものが存在しています。コンソールからKMSを作成する際には、以下のポリシーステートメントがデフォルトで設定されています。
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
}
IAMで権限を管理したい
他のリソースポリシーが利用できるサービスではデフォルトでIAMを用いたアイデンティティベースでの権限管理が行えます。しかし、KMSではrootユーザーに権限がなければアイデンティティベースの権限管理はできません。
このデフォルトのキーポリシーステートメントにより、アカウントは IAM ポリシーを使用して、KMS キーに対するすべてのアクション (
https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/key-policy-default.html より引用kms:*
) の許可を委譲することができます。
つまり、デフォルトのキーポリシーはrootユーザーに当該キーの全権を与えているというだけでなく、IAMでの権限の管理も可能にしてくれているということです。
以上のことから、IAMでの権限管理はrootユーザーが持つ権限を継承するという形で行われているのではないか、と個人的に推測しています。
IAMで権限を与えたくない
rootユーザーはAWSアカウントないで絶対に削除されないユーザーです。何か問題が発生したときの為に、rootユーザーにはKMSの権限を持たせたいというケースは容易に想像できます。
一方で、デフォルトのキーポリシーでrootユーザーに権限を与えると、IAMでも権限が管理できてしまいます。
S3でログを保存する際に暗号化するためだけに使用する、つまり対象のS3バケット以外はKMSを使用する必要がない場合、IAMで権限を与えることが出来てしまうのは好ましくありません。
なぜなら、想定外のIAMユーザーやIAMロールなどがKMSの権限を持つ可能性が出てきてしまうからです。
では、rootユーザーに権限を与えつつ、IAMでは権限を与えられないようにするにはどうすればよいのでしょうか。解決策は、以下のようなキーポリシーを設定することです。
{
"Sid": "EnableRootAccessAndPreventPermissionDelegation",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalType": "Account"
}
}
}
ポイントは、以下の部分です。
"Condition": {
"StringEquals": {
"aws:PrincipalType": "Account"
}
}
aws:PrincipalTypeがAccountであるとは、プリンシパル(行為の主体)がAWS アカウントのルートユーザーであることを意味します。この条件付けにより、IAMでは権限の管理を行えないようにすることが出来ます。
IAM ポリシーが AWS KMS の KMS キーへのアクセスをユーザーまたはロールに許可しないようにするにはどうすればよいですか?
ポリシー変数に使用可能なリクエスト情報
グラント
KMSでは、キーポリシーやIAMのほかに、グラントという機能を使用して権限を管理することが出来ます。一時的に権限を与えその後すぐにその権限を停止したり、暗号化のみを許可したりというように、より柔軟で細かな権限の管理を行うことが出来ます。
対象となるキーに「CreateGrant」という操作が可能であるグラントの付与者となるプリンシパルが、グラントの被付与者となるプリンシパルへ権限を与えることが出来ます。与えられる権限はグラントオペレーションに該当する操作のみとなっています。
付与者となるプリンシパルはCreateGrantの権限さえ持っていれば、グラントオペレーションに含まれるDescribeKeyの権限を持っている必要はありません。
このように、グラントは柔軟で細かい設定ができる分、非常にややこしくわかりづらい機能であるため、使用する際はデベロッパーガイドをしっかり読み込むことをお勧めします。
ちなみに、EC2がKMSを使って暗号化されたEBSと通信を行う際にはグラントが利用されているらしいです。EC2インスタンスにはID専用ロールというものがアタッチされており、そのロールのおかげでEBSに対してCreateGrandができるらしいです。
このID専用ロールは手動で作成または削除する必要はなく、ポリシーも関連付けられていないそうです。自動的付与されているということか?
また、ID専用ロールはサービスコントロールポリシー (SCP) と KMS キーポリシーが適用されるとのことです。調べてもあまり情報が出てこず、よくわかりませんでした。
Amazon EBS 暗号化
EBSの暗号化は少し複雑なので、AWS Certified Security Specialtyを受験される方はこちらもチェックしておくとよいと思います。
最後に
今回の記事のポイントは以下の4点です。
- キーポリシーはKMSのリソースベースポリシー
- KMSはキーポリシーでrootユーザーに対しても明示的に権限を与える必要がある
- キーポリシーでrootユーザーに権限を与えることでIAMでの管理が可能になる
- グラントを利用すればきめ細かい権限の管理が可能になる
AWSを学ぶ際に混乱するポイントとして権限周りはよく挙げられると思います。
そのなかでもKMSは特に難しいと思います。この記事を見て理解を深めていただけると嬉しいです。
また、記事作成に当たって調査を行う際に
- ポリシーで設定するcondition要素
- グラント
- ID専用ロール
など、よく理解できていない概念はいくらでもあると思い知らされました。
特にID専用ロールは聞いたこともなく、もっと精進しようと思いました。
ご一読いただきありがとうございました!