[TIL] 9. AWS セキュリティ管理機能

IAM Roleの仕組みを再確認
EC2などのプリンシパルがIAM Roleに割り当てられた権限を用いてリソースにアクセスする際の流れは以下の図のようになっている。
- プリンシパルはIMDS(169.254.169.254)に認証情報の取得リクエストを送信する。IMDSが既に一時的な認証情報を持っていれば、この時点で対象リソースにアクセス可能。
- IMDSがリクエストを受け取り、STSに対してAssumeRole実行(sts:AssumeRoleから分かるように、直接IAMに依頼するのではなく「窓口」に相当するSTSにリクエストを送る。IAM Roleは対応関係を記したデータベース的な扱いであり、STSが仲介人となる。)
- STSはIAM Roleに記された対応関係に基づき、一時的な認証情報を生成し、IMDSに返却する。
- プリンシパルはIMDSから一時的な認証情報を受け取り、対象リソースにアクセスする。

IAM Roleの「セッションを取り消す」ことで一時的な認証情報が削除される。

KMSの仕組みを再確認
KMSではCDKとCMKという二つの鍵を使用して、暗号・復号している。
- CDK:実際のデータを暗号化する。クライアント側で暗号化されたCDKを保管する。
- CMK:CDKを暗号化する。AWS側で暗号化されたCMKを保管する。
KMSによる暗号化
- 暗号化に必要なCDKの発行の依頼を行う(
kms:GenerateDataKey
) - KMS内のHSMでCDKを作成する
- 作成されたCDKをKMSホストに渡す
- 暗号化されたCMKをHSMに取り出す
- HSM内で暗号化されたCMKを復号する
- CMKでCDKを暗号化したものをKMSホストに渡す
- CDKと暗号化されたCDKをクライアントに返す
- CDKでデータを暗号化する
- 暗号化されたデータと暗号化されたCDKを保存する
KMSによる復号化
- 暗号化されたCDKを復号するために必要なCMKをKMSに依頼する(
kms:Decrypt
) - 暗号化されたCMKをHSMに取り出す
- HSM内で暗号化されたCMKを復号する
- CMKをKMSホストに渡す
- CMKをクライアントに返す
- クライアント側に保管されている暗号化されたCDKを取り出し、CMKによって復号する
- CDKによって暗号化されたデータを復号する

カスタマー管理CMK「デフォルトキーポリシー」の重要な役割
KMSは少し特殊で、基本的にはIAMポリシーだけではアクセス権限を管理できない。つまり、以下の二つのパターンでのみアクセス管理が可能ということになる。
- キーポリシーのみ
- IAMポリシー+キーポリシー
しかし、実際にはIAMポリシーのみによる制御が可能となっている。この理由は、以下に示したデフォルトのキーポリシーにある。一見するとrootユーザにKMSのフル権限を与えているだけだが、もう一つ重要な役割がある。"Enable IAM User Permissions"とあるように、この「おまじない」を定義することで、IAMポリシーによる制御が有効になるのだ。つまり、この「おまじない」が定義されていると、キーポリシーで明示的に許可されていないIAMユーザでも、IAMポリシーで許可されていればkmsアクションを実行できるようになる。
デフォルトポリシーは名前の通り、デフォルトで適用されているため、結果的にKMSもIAMポリシーだけでアクセス権限を管理することが可能となる。「IAMポリシー + キーポリシー = IAMポリシーのみ」になるということ。
{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::685777150417:root"
},
"Action": "kms:*",
"Resource": "*"
}
]
}

AWS管理CMKはPrincipal側でのIAMによる許可は不要
aws/s3などのAWS管理KMSキーにおいては、基本的にキーポリシー側でAction権限を許可しているためIAMロール/ユーザ側で許可を定義する必要はない。
{
"Version": "2012-10-17",
"Id": "auto-s3-2",
"Statement": [
{
"Sid": "Allow access through S3 for all principals in the account that are authorized to use S3",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
~~~~~~~~~~~~以下省略~~~~~~~~~~~~

SNSトピックの暗号化の際にはカスタマー管理CMKを使用する
SNSトピックの暗号化を有効にした場合には、メッセージを発行する側(CloudWatchやEventBridge)にkms:Decrypt
権限とkms:GenerateDataKey
権限を与える必要がある。
そのために、キーポリシーを変更できるカスタマー管理CMKを使用しなければならない。

考察
SNSトピックの暗号化は「保管中の暗号化」を指しているのに、なぜCloudWatchやEventBridgeに権限を与えるのかは疑問が残る。普通に考えればSNSトピック側からkms:GenerateDataKey
とkms:Decript
を呼び出し、メッセージを暗号・復号するべきだと思う。
CMKのキーポリシーに、SNSに対する権限ではなく、メッセージを発行する側に対する権限を明記する必要があるという状況から判断すれば、暗号化・復号化は全てメッセージを発行する側に任されていると考えるのが自然である。SNSでは暗号・復号化は一切行わず、発行する側に全て任せている状態なのだろう。