KMS の key policy に root ユーザーの定義が必要なのはなぜか?

Posted on

KMS (CMK) の key policy について曖昧にしか理解していないところがあったので調べ直しました。

具体的には、デフォルトの key policy にある次のような定義です。この意味をちゃんと理解できていなかったので、"Using key policies in AWS KMS" に書いてあることを実際に試しながら理解していきます。

{
    "Sid": "Enable IAM policies",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::111122223333:root"
    },
    "Action": "kms:*",
    "Resource": "*"
}

この key policy が必要な理由

"Allows access to the AWS account and enables IAM policies" には次のような説明があります。

1. Reduces the risk of the CMK becoming unmanageable.

You cannot delete your AWS account's root user, so allowing access to this user reduces the risk of the CMK becoming unmanageable.

(snip)

The root user does not have access to the CMK, because the root user can access a CMK only when the key policy explicitly allows it. This is different from most other resources in AWS, which implicitly allow access to the root user.

AWS アカウントの root ユーザーは削除することができません。 root ユーザーに CMK の権限を与えておくことで、管理者権限を持つ IAM user / role を誤って削除してしまっても root ユーザーから操作することができます。他の AWS リソースと異なり、CMK は root ユーザーであっても key policy で明示的に許可しないとアクセスできません。

2. Allows IAM policies to control access to the CMK.

Every CMK must have a key policy. You can also use IAM policies to control access to a CMK, but only if the key policy allows it. If the key policy doesn't allow it, IAM policies that attempt to control access to a CMK are ineffective.

自分が理解できていなかったのはこの 2 番目の説明です。 CMK のアクセス制御は IAM policy でもできますが、その前提として key policy で root ユーザーに KMS の権限を与える必要があります。そうしないと CMK のアクセスを制御しようとする IAM policy は有効になりません。

実際に試してみる

root ユーザーに権限を与えていない key policy で CMK を作ります。 manabusakai ユーザーは Management Console にログインして操作しているユーザーです。

{
    "Id": "key-consolepolicy-1",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::111122223333:user/kms-test-1",
                    "arn:aws:iam::111122223333:user/manabusakai"
                ]
            },
            "Action": "kms:*",
            "Resource": "*"
        }
    ]
}

root ユーザーに権限を与えていないので、IAM policy は有効にならず key policy だけが評価されます。その証拠に kms-test-1 ユーザーの IAM policy が空っぽでも API を呼べました。

次に kms-test-2 ユーザーを作って AdministratorAccess の managed policy を紐付けます。 AdministratorAccess なので "Action": "*" の強い権限を持っていますが、API を呼ぶと AccessDenied になります。 CloudTrail には次のようなエラーメッセージが出ていました。

User: arn:aws:iam::111122223333:user/kms-test-2 is not authorized to perform: kms:Decrypt on resource: arn:aws:kms:ap-northeast-1:111122223333:key/(snip)

このことからも IAM policy が有効になっていないことがわかります。

先ほどの CMK の key policy に root ユーザーの権限を追加して IAM policy が有効になることを確認します。

{
    "Id": "key-consolepolicy-1",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::111122223333:user/kms-test-1",
                    "arn:aws:iam::111122223333:user/manabusakai"
                ]
            },
            "Action": "kms:*",
            "Resource": "*"
        }
    ]
}

key policy の中に kms-test-2 ユーザーに関する定義はありませんが、root ユーザーに権限を与えたことで IAM policy が有効になり API が呼べるようになりました。

まとめ

  • 万が一に備えて、CMK の key policy で root ユーザーに権限を与えておく
  • root ユーザーに権限を与えると IAM policy が有効になる

直感的に理解しづらいのですが、root ユーザーに権限を与えることで IAM policy が有効になることを確認できました。 IAM policy と key policy の関係を曖昧に理解していたので、よい復習になりました。