security
A
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
KMSキーポリシーの設計 — IAMポリシーとの関係・ロックアウト防止・クロスアカウント
KMSキーポリシーとIAMポリシーの評価の違い、アカウントルートAllow必須の理由、キーポリシーのみでの制御パターン、クロスアカウントでのKMS使用設定を解説。
一言結論
KMSキーポリシーにアカウントルートへのAllow記述がなければIAMポリシーだけではキーを使えず、誰もアクセスできないロックアウト状態になるため、キーポリシー設計はS3等のリソースポリシーとは別のルールとして理解する必要がある。
KMSキーポリシーの特殊性
KMSキーポリシーは他のリソースポリシーと異なる特殊なルールを持つ。最も重要な点は「キーポリシーなしではIAMポリシーだけでKMSキーを使えない」という点だ。
通常のS3バケットポリシー(同一アカウント):
IAMポリシーのAllow OR バケットポリシーのAllow → アクセス可
KMSキーポリシー(同一アカウント):
キーポリシーにAllow記述がなければIAMポリシーのAllowは無効
→ キーポリシーにアカウントルートへのAllow記述が必須
アカウントルートへのAllow記述
// ✅ 正しいキーポリシーの基本形
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "kms:*",
"Resource": "*"
}
]
}
この記述があることで「IAMポリシーでKMSへのアクセスを制御できる」状態になる。記述がないと誰もキーを使えなくなる(ロックアウト)。
キーポリシーのみでアクセス制御する場合
キーポリシーにIAMロール/ユーザーを直接指定することでIAMポリシー不要でアクセスを制御できる。
{
"Statement": [
{
"Sid": "Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/KMSAdminRole"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion",
"kms:TagResource",
"kms:UntagResource"
],
"Resource": "*"
},
{
"Sid": "Key Users",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:role/AppRole",
"arn:aws:iam::123456789012:role/LambdaRole"
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}
クロスアカウントでのKMS使用
クロスアカウントでCMKを使う場合、キーポリシーとIAMポリシーの両方が必要だ(他のリソースポリシーと同じルール)。
// アカウントAのCMKのキーポリシー: アカウントBへのAllow
{
"Statement": [{
"Sid": "Cross Account Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::987654321098:root"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}]
}
// アカウントBのIAMポリシー: アカウントAのCMKへのAllow
{
"Statement": [{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "arn:aws:kms:ap-northeast-1:123456789012:key/xxx"
}]
}
キーポリシーでのサービス使用許可
AWSサービス(S3, EBS等)がCMKを使うためのキーポリシー設定。
// S3 サーバーサイド暗号化にCMKを使用許可
{
"Statement": [{
"Sid": "Allow S3 Service",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey*",
"kms:Decrypt"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:CallerAccount": "123456789012",
"kms:ViaService": "s3.ap-northeast-1.amazonaws.com"
}
}
}]
}
kms:ViaService 条件を使うことで「特定のAWSサービス経由のみキーを使用可能」に制限できる。
グラント(Grants)とキーポリシーの違い
キーポリシー: 静的、変更にIAM権限が必要
グラント: 動的、プログラムから作成/削除可能
特定の操作のみ委任できる(Constraints付き)
グラントの適切な使い方:
- 一時的なアクセス権限の付与
- AWS統合サービス(EBS, ECS等)への内部的な委任
- プログラムによる動的な権限管理
KMSアクション一覧(重要なもの)
管理操作:
kms:CreateKey, kms:DeleteKey
kms:EnableKey, kms:DisableKey
kms:PutKeyPolicy, kms:GetKeyPolicy
kms:ScheduleKeyDeletion, kms:CancelKeyDeletion
暗号化操作:
kms:Encrypt, kms:Decrypt
kms:ReEncrypt* (キーの再暗号化)
kms:GenerateDataKey, kms:GenerateDataKeyWithoutPlaintext
署名操作(非対称キー):
kms:Sign, kms:Verify
kms:GetPublicKey
ローテーション:
kms:EnableKeyRotation, kms:DisableKeyRotation
kms:GetKeyRotationStatus
ロックアウトの防止
# キーポリシーを更新する前に必ずバリデーション
# コンソールで変更→プレビューで確認
# CLIでキーポリシー更新(BypassPolicyLockoutSafetyCheck使用は避ける)
aws kms put-key-policy \
--key-id alias/my-key \
--policy-name default \
--policy file://key-policy.json
# BypassPolicyLockoutSafetyCheck はルートユーザーのみのAllow削除等の
# 危険な操作を強制的に行うフラグ。通常は使わない
試験頻出ポイント
- キーポリシーにルートAllow記述がなければIAMポリシーが効かない
- クロスアカウントKMSはキーポリシー+IAMポリシーの両方が必要
kms:ViaServiceで特定サービス経由のみに制限可能- キーポリシーは最大32KBまで
- 削除前のキーはdisabledにはできるが、kms:Decryptが必要な場合は注意
まとめ
KMSキーポリシーの核心はアカウントルートへのAllow記述の必要性だ。これがないとIAMポリシーでの制御が機能しなくなるロックアウトが発生する。クロスアカウント設定では双方向のAllow、サービス連携ではkms:ViaService条件を使った精密な制御が推奨される。