KMS CMK 使用時に IAM ポリシーとキーポリシーで許可していないにもかかわらず CMK を使用できる理由を教えてください

KMS CMK 使用時に IAM ポリシーとキーポリシーで許可していないにもかかわらず CMK を使用できる理由を教えてください

2022.08.29

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

Here is the English version

困っていた内容

Lambda で環境変数の暗号化に KMS CMK を使用しています。
CMK を使用するには Lambda の 実行ロールに付与する IAM ポリシーまたは CMK のキーポリシーで CMK の使用を許可する必要があるという認識でした。
しかし、どちらでも許可していないにもかかわらず Lambda で CMK を使用できました。

KMS CMK 使用時に IAM ポリシーとキーポリシーで許可していないにもかかわらず CMK を使用できる理由を教えてください。

どう対応すればいいの?

KMS の Grants によってアクセスが許可されている可能性があります。
Grants in AWS KMS - AWS Key Management Service

A grant is a policy instrument that allows AWS principals to use KMS keys in cryptographic operations. It also can let them view a KMS key (DescribeKey) and create and manage grants. When authorizing access to a KMS key, grants are considered along with key policies and IAM policies.

KMS でのアクセス許可は以下の 3 つによって決定されます。

  • IAM ポリシー
  • キーポリシー
  • Grants

IAM ポリシーとキーポリシーでアクセスを許可していなくても Grants でアクセスが許可されていれば CMK を使用可能です。

KMS によるアクセス許可については以下の AWS 公式ドキュメントのフローチャートもご参照ください。
Troubleshooting AWS KMS permissions - AWS Key Management Service

また、Grants でのアクセスが許可されているかを確認するには ListGrants API をご利用ください。

やってみた

Lambda の環境変数の暗号化に CMK を使用した際にどのように Grants でアクセス許可が付与されるのかを確認してみました。

まずは検証用に KMS で CMK を作成しました。
キーポリシーではスイッチロールで使用している IAM ロールからのアクセスのみを許可し、Lambda の実行ロールからのアクセスは定義しません。

{
  "Version": "2012-10-17",
  "Id": "key-consolepolicy-3",
  "Statement": [
    {
      "Sid": "Allow access for Key Administrators",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::012345678901:role/my-role"
      },
      "Action": "kms:*",
      "Resource": "*"
    }
  ]
}

続いて検証用にデフォルト設定で Lambda 関数を作成しました。
Lambda 関数をデフォルト設定で作成すると以下のような権限を持った IAM ロールも自動的に作成されます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:ap-northeast-1:012345678901:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:ap-northeast-1:012345678901:log-group:/aws/lambda/function-name:*"
            ]
        }
    ]
}

上記 Lambda の実行ロールにも CMK へのアクセス権は付与されていません。

環境変数を設定する前に AWS CLI の list-grants コマンドで現在の Grants を確認してみます。

$ aws kms list-grants --key-id my-key-id

{
    "Grants": []
}

環境変数設定前では Grants でのアクセス許可は付与されていないことがわかりました。

ここで Lambda の環境変数を作成して CMK で暗号化してみます。
2025-11-05_09h34_47

この状態で再度 list-grants コマンドを実行してみます。

$ aws kms list-grants --key-id my-key-id

{
    "Grants": [
        {
            "KeyId": "arn:aws:kms:ap-northeast-1:012345678901:key/xxx",
            "GrantId": "60f37ec4106eb161780bd5530a3564e62cb0935a831661372f93a7e8670299df",
            "Name": "test/8135ba14-4a6f-495a-8b59-80730abb9fa2",
            "CreationDate": "2025-11-05T00:43:25+00:00",
            "GranteePrincipal": "arn:aws:sts::012345678901:assumed-role/test-role-cu5o193j/test",
            "RetiringPrincipal": "lambda.ap-northeast-1.amazonaws.com",
            "IssuingAccount": "arn:aws:iam::012345678901:root",
            "Operations": [
                "Decrypt",
                "RetireGrant"
            ],
            "Constraints": {
                "EncryptionContextEquals": {
                    "aws:lambda:FunctionArn": "arn:aws:lambda:ap-northeast-1:012345678901:function:test"
                }
            }
        }
    ]
}

環境変数を設定することで以下の 2 つの権限が自動的に付与されていたため、Lambda コンソールから環境変数の暗号化に CMK を指定すると自動的に Grants による権限が付与されるようです。

  • Decrypt
  • RetireGrant

CMK へのアクセス確認として以下のコードで Lambda 関数を実行してみます。

exports.handler = async (event) => {

    console.log(process.env.key);
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

上記のコードで環境変数の値を出力できることを確認できました。

2025-11-05T00:45:17.325Z	f73b66f6-7f7f-40e1-9730-f3d472bcf503	INFO	value

今度は retire-grant コマンドで Grants によるアクセス権限を削除した際の挙動を確認してみます。

$ aws kms retire-grant \
--key-id my-key-arn \
--grant-id 60f37ec4106eb161780bd5530a3564e62cb0935a831661372f93a7e8670299df

再度 list-grants コマンドを実行してみます。

$ aws kms list-grants --key-id my-key-id

{
    "Grants": []
}

Lambda に付与されていた Grants によるアクセス権限が削除されていることが確認できました。
この状態で再度 Lambda を実行すると以下のエラーが発生しました。

API アクションの呼び出しに失敗しました。
エラーメッセージ: Lambda was unable to decrypt the environment variables because KMS access was denied. Please check the function's KMS key settings. 
KMS Exception: AccessDeniedExceptionKMS Message: User: arn:aws:sts::012345678901:assumed-role/test-role-cu5o193j/test is not authorized to perform: kms:Decrypt on resource: arn:aws:kms:ap-northeast-1:012345678901:key/xxx because no resource-based policy allows the kms:Decrypt action (Service: Kms, Status Code: 400, Request ID: 7c2b4065-21a8-4e9f-b965-b1243ae09441) (SDK Attempt Count: 1)

Grants を削除したことにより IAM ポリシー、キーポリシー、Grants のいずれでもアクセスが許可されていないため上記のアクセス拒否エラーが発生している状態です。
この状態では Lambda のコードは実行されておらず実行ログも出力されませんでした。

以上より、IAM ポリシーとキーポリシーでアクセスを許可していなくても Grants でアクセスが許可されていれば CMK を使用可能な点を確認できました。

参考資料

この記事をシェアする

FacebookHatena blogX

関連記事