やりたかったこと
- KMSの鍵利用を一部のユーザのみに許可したい
- 同一アカウント内のEC2インスタンス内で利用する
- 対向AWSアカウント内のEC2インスタンス内でも利用する
- 許可されたユーザ以外の鍵の利用は拒否したい
NotPrincipal で除外設定を書いてみる
KMSのCMKにはリソースポリシー(キーポリシー)が設定できるので、 "Effect: "Deny"
のポリシー内で "NotPrincipal"
を使って一部ユーザ/ロール以外の利用を弾こうと思った。書いたポリシーはこんな感じ:
{
"Sid": "Deny use of the key without specific role/user",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::111122223333:root",
"arn:aws:iam::111122223333:role/role-a",
"arn:aws:sts::111122223333:assumed-role/role-a/i-123456789012345678"
"arn:aws:iam::111122223333:user/user-b",
"arn:aws:iam::444455556666:root",
"arn:aws:iam::444455556666:role/role-c",
"arn:aws:sts::444455556666:assumed-role/role-c/i-987654321098765432"
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "*"
},
ポイントは次の2点。
- 除外対象のロール/ユーザを指定するのははもちろん、そのユーザが所属するアカウントも除外対象に含める必要がある
- ロールを除外するときには、AssumeRoleしたロールユーザも除外設定に含める必要がある
- ここではEC2インスタンスプロファイルがAssumeRoleするときを想定して、EC2インスタンスIDを指定している
もちろん、上記のDenyポリシーに加えて、Allowポリシーを作成する必要がある。(AllowポリシーはKMS CMKを作るときにデフォルトで設定されるので省略)
何が辛いか
ポリシーを見ればわかるが、IAM ロールを除外をするためにAssumeRoleしたロールユーザも指定する必要がある点が非常に辛い。
今回のようにEC2にアタッチしたIAMロールの場合、キーポリシーにはARN内でEC2インスタンスIDを指定する必要がある。したがって、EC2インスタンスが増えたりインスタンスを作り直したりした場合はいちいちキーポリシーを見直す必要が生じる。当然ながらAutoScaling環境ではこの方法は採用できない。
また、管理外のアカウントにあるIAMロールを除外する場合、そちらの変更を追いかけなければならず、対向の管理者とのコミュニケーションコストが高くなってしまう。
というわけで、今回はこの方法は不採用とした。
結局どうしたか
仕方ないので、いわゆるパワーユーザー的なIAMユーザとロールを洗い出して、Denyポリシーを付与することに……
これはこれで非常に辛いが、管理対象のAWSアカウントで閉じるのでまだまし。
どういうときにNotPrincipalは使えるか
こちら に書いてあった。S3バケットへのアクセスを特定のLambdaに絞るのには使えそう。