[アップデート] AWS KMS でタグもしくはエイリアスを利用した ABAC(Attribute-Based Access Control) がサポートされました!
コンバンハ、千葉(幸)です。
AWS KMS が、タグもしくはエイリアスを使用した ABAC (Attribute-Based Access Control)に対応しました!
より細やかに権限制御できるようになりましたね。
ABAC(Attribute-Based Access Control)とは
ABAC とは、属性に基づいてアクセス許可を定義する認証戦略です。属性は、多くの AWS リソースにおいてはタグが該当します。
以下のイメージをご覧ください。
(AWS の ABAC とは - AWS Identity and Access Managementより)
左側の IAM ロール、および右側の AWS リソース( S3 オブジェクト、 EC2 インスタンス)にはそれぞれの属性に応じてタグが付与されています。環境や部門、プロジェクトなど切り口は様々ありますが、タグに応じた分類が行われています。
ここで、各 IAM ロールには「自身と同じタグが割り振られている AWS リソースに対してはアクション可能」という共通したポリシーが適用されています。
リソースが増えてもロールが増えても、タグ付けがきちんとされている環境であれば、共通したポリシーで統一的に管理を行えます。
こういった制御を行うためには、「リソースにこのタグ(属性)がついているとき〇〇可能」という IAM 条件キーが、実行したい アクションに対応している必要があります。
一方で、従来からの考え方である RBAC(Role-based access control)においては、役割ごとにポリシーを定義する必要があります。
(画像引用元同上)
ここでは、「この AWS リソースに対してアクション可能」というものを個別に定義していくことになります。リソースが増えればそれを追加で許可する必要がありますし、ロールが増えれば新たにポリシーを作成する必要があります。
AWS KMS ではこれまで ABAC には対応していませんでしたが、今回のアップデートでタグもしくはエイリアスを使用した ABAC がサポートされました。タグ以外の属性で ABAC に対応したのは珍しいですね。
KMS のエイリアスとは
KMS のエイリアスは、カスタマー管理キー(CMK)に関連づけることで「判別しやすさ」を提供してくれるものです。
CMK を作成した際に割り振られる一意のキー ID は以下のような形式で、非常に判別しづらいです。
xxx743a8-exx6-4xxe-9xx0-xxx3b2fb1d15
このキー ID の別名としてエイリアスを設定できます。マネジメントコンソールから操作したり AWS CLI から操作したりする際に、長ったらしいキー ID ではなくこのエイリアスを指定できるようになります。
また、エイリアスは CMK とは独立したリソースです。以下のような考え方となります。
- ひとつの CMK に複数のエイリアスを関連づけできる
- ひとつのエイリアスを同時に複数の CMK に関連づけできない
- CMK にエイリアスを関連づけしないこともできる
タグは「キーと値」の組み合わせからなりますが、エイリアスは「キーのみ」です。似ているようで、少し異なる概念ですね。
IAM ポリシーとキーポリシー
今回のアップデートについて理解する上で、「ポリシー」が二種類あることを押さえておきましょう。
IAM ユーザーやロールなどの IAM エンティティが CMK に対してアクションを実行する際、その成否は両者に設定されたポリシーによって決定されます。( VPC エンドポイント経由の実行であったりOrganizations 配下での実行であったりなど、他のポリシーによる影響を受ける場合もあります。)
ここでは IAM 側に設定されたポリシーを IAM ポリシー、 CMK 側に設定されたポリシーをキーポリシーと呼びます。
IAM ポリシーによるアクセスを可能にするためには、キーポリシー側で許可が与えられている必要があります。
例えば以下のようなポリシーを 特定のCMK のキーポリシーに設定するとします。
{ "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::111122223333:root"}, "Action": "kms:*", "Resource": "*" }
上記の状態では、以下のエンティティが当該 CMK に対してアクセス可能になります。
- アカウント
111122223333
の root アカウント- 任意のアクションを実行可能
- アカウント
111122223333
の IAM のうち、IAM ポリシーで許可を与えられたもの- ポリシーで許可を与えられたアクションのみ実行可能
アップデートで追加された IAM 条件キー
今回のアップデートにより追加された IAM 条件キーを確認します。
条件キーによって、それを使用できるポリシーが変わります。以下パターンに分かれます。
- IAM ポリシーのみで使用できる
- IAM ポリシーとキーポリシーで使用できる
前述の通り、 IAM ポリシーでアクセスを可能にするためにはキーポリシー側で許可されている必要がある、ということにご注意ください。
タグによるコントロールを行うものとエイリアスによるコントロールを行うものを分けて記載します。
タグによるコントロール
ABAC条件キー | 説明 | 使用できるポリシータイプ | 条件を使用できるアクション |
---|---|---|---|
aws:ResourceTag | CMKに付与されているタグ(キーと値)によるコントロール | IAMポリシーのみ | 特定のCMKリソースオペレーション(後述) |
aws:RequestTag | タグ操作リクエストにおけるタグ(キーと値)によるコントロール | キーポリシーとIAMポリシー | TagResource、 UntagResource |
aws:TagKeys | タグ操作リクエストにおけるタグキーによるコントロール | キーポリシーとIAMポリシー | TagResource、 UntagResource |
1番目は「特定のタグが付与されている CMK に対してのみアクション可能(あるいは禁止)」というコントロールを実現するためのものです。(この条件キーを使用できるアクションは後述します。)
例えば以下のようなポリシーであれば、キーがPurpose
、値がTest
というタグがついた CMK に対していくつかのアクションを実行できる、ということになります。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKey*" "kms:DescribeKey", ], "Resource": "arn:aws:kms:*:111122223333:key/*", "Condition": { "StringEquals": { "aws:ResourceTag/Purpose": "Test" } } ] }
2番目と3番目は、「特定のタグのみ タグづけ/タグ除去 が可能(あるいは禁止)」というコントロールを行うものです。
エイリアスによるコントロール
ABAC条件キー | 説明 | 使用できるポリシータイプ | 条件を使用できるアクション |
---|---|---|---|
kms:ResourceAliases | CMKに関連付けられたエイリアスによるコントロール | IAMポリシーのみ | 特定のCMKリソースオペレーション(後述) |
kms:RequestAlias | リクエストの中のエイリアス( CMK を表すもの)によるコントロール | キーポリシーとIAMポリシー | 暗号化操作(※)、 DescribeKey、 GetPublicKey |
タグによるコントロールとは少し趣が異なりますね。
2番目のkms:RequestAlias
は、リクエストにおけるエイリアスを評価対象とします。
例えば AWS CLI で DescribeKey の API を実行する際には、対象を以下のようにエイリアスで指定できます。(キー ID で指定することもできます。)
$ aws kms describe-key\ --key-id alias/Test-Key
こういったケースで特定のエイリアスを持つ CMK に対するアクションを許可/禁止できる、という条件キーがkms:RequestAlias
です。
また、表中における暗号化操作(※)とは、以下を指します。(ややこしいので余裕があったら見てください。)
Operation | CMK key type | CMK key usage |
---|---|---|
Decrypt | Any | ENCRYPT_DECRYPT |
Encrypt | Any | ENCRYPT_DECRYPT |
GenerateDataKey | Symmetric | ENCRYPT_DECRYPT |
GenerateDataKeyPair | Symmetric | ENCRYPT_DECRYPT |
GenerateDataKeyPairWithoutPlaintext | Symmetric | ENCRYPT_DECRYPT |
GenerateDataKeyWithoutPlaintext | Symmetric | ENCRYPT_DECRYPT |
GenerateRandom | N/A. This operation doesn't use a CMK. | N/A |
ReEncrypt | Any | ENCRYPT_DECRYPT |
Sign | Asymmetric | SIGN_VERIFY |
Verify | Asymmetric | SIGN_VERIFY |
特定の CMK リソースオペレーション
ここまでの表で「特定の CMK リソースオペレーション」としていた部分に関しては、以下のドキュメントから確認できます。
ここでは KMS に関するアクション(およびパーミッション)と、それを使用できるポリシーや条件キーが表でまとめられています。
この表で、リソース列が CMK
となっているもので、上述の条件キーが使用できます。
初見でポリシータイプ列が「キーポリシー」となっていることに混乱した( IAM ポリシーじゃないの??)のですが、以下の脚注がありました。
Key policy means that you can specify the permission in the key policy. When the key policy contains the policy statement that enables IAM policies, you can specify the permission in an IAM policy.
機械翻訳の結果はこちら。
キーポリシーとは、キーポリシーにパーミッションを指定できることを意味します。キーポリシーにIAMポリシーを有効にするポリシーステートメントが含まれている場合、IAMポリシーでパーミッションを指定することができます。
ポリシータイプ列において「 IAM ポリシー」となっているものは、キーポリシーでは使用できないことを表します。
タグによるコントロールかエイリアスによるコントロールか
どちらのパターンでも柔軟でスケーラブルなアクセス制御が可能ですが、両者の考え方はわずかに異なります。どちらを選択すべきかは、既存の AWS の使用パターンによって変わります。
例えば、すでにほとんどの管理者にタグづけ権限が広く与えられている場合には、(それを絞っていくよりは)エイリアスに基づいたコントロールを行う方が簡単に済む場合が多いでしょう。
エイリアスに関するクォータが上限に近い場合には、タグを使用する方が好ましいこともあります。
それぞれのパターンによるメリットは以下の通りです。適したものを選択してください。
タグによるコントロールのメリット
他の AWS リソースと共通したタグを使用できる
すでに他の AWS リソースでタグベースのアクセス制御を行っている場合には、それを CMK にも踏襲できます。「他のリソースはタグベースだけど CMK ではエイリアスベース」とするよりは、一本化した方がメリットが出る場合もあるでしょう。
複数の CMK をグルーピングして使用できる
エイリアスは複数の CMK に対して同一のものを関連づけできない、というのは先述の通りです。複数の CMK に対してコントロールを行いたい場合には、それらに共通したタグを付与することによって簡単にグルーピングができます。
エイリアスによるコントロールのメリット
エイリアスに基づいた暗号化操作へのコントロールが可能
先ほど確認したkms:RequestAlias
条件キーは、リクエストに含まれるエイリアスに応じてコントロールができます。これはタグによるコントロールの条件キーでは無い考え方です。
単一の CMK に限定したコントロールができる
タグベースの場合と逆の考え方となりますが、複数の CMK をグルーピングしたコントロールができない、ということがメリットになる場合もあります。エイリアスは AWS アカウントおよびリージョンにおいて一意である必要があり、また、同時に関連づけられる CMK も一つです。厳密なコントロールが要求される場合にはグルーピングせず単一で扱う方が適しているでしょう。
(エイリアスベースであっても、alias/test*
など、ワイルドカードを使用することで複数の CMK を対象とすることはできます。)
やってみた
今回は以下のようなケースで試してみました。
IAM ユーザーにはAdministratorAccess
を与えつつも、特定の条件で Deny するポリシーを作成してアタッチしています。
条件とは、「特定の値以外のエイリアスに対するリクエストである場合」です。そして「特定の値」とは、「自身に付与されたProject
タグの値」です。ポリシーの内訳は以下です。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "kms:DescribeKey" ], "Resource": "arn:aws:kms:*:000000000000:key/*", "Condition": { "StringNotEquals": { "kms:RequestAlias": "alias/${aws:PrincipalTag/Project}" } } } ] }
今回は IAM ユーザーにはProject:HOGEHOGE
タグを付与しているので、「何でもできるけど、 HOGEHOGE 以外のエイリアスが関連づけられた CMK を Describe することができない」という状態です。
CMK は以下が存在しており、どちらもキーポリシーで IAM ポリシーによるアクセスを許可しています。
{ "Id": "key-consolepolicy-3", "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::000000000000:root" }, "Action": "kms:*", "Resource": "*" } ] }
この状態でエイリアス HOGEHOGE を指定してaws kms describe-key
を実行すると、問題なく成功します。
% aws kms describe-key\ --key-id alias/HOGEHOGE { "KeyMetadata": { "AWSAccountId": "000000000000", "KeyId": "xxxxxxxx-7f6d-4290-b6ff-182b2ae6dd6f", "Arn": "arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-7f6d-4290-b6ff-182b2ae6dd6f", "CreationDate": "2020-07-16T01:01:01.811000+09:00", "Enabled": true, "Description": "", "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "Origin": "AWS_KMS", "KeyManager": "CUSTOMER", "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT", "EncryptionAlgorithms": [ "SYMMETRIC_DEFAULT" ] } }
エイリアスで Test-Key を指定すると、失敗します。
% aws kms describe-key\ --key-id alias/Test-Key An error occurred (AccessDeniedException) when calling the DescribeKey operation: User: arn:aws:iam::000000000000:user/chiba-cli is not authorized to perform: kms:DescribeKey on resource: arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-e066-4bde-95e0-5ac3b2fb1d15 with an explicit deny
エイリアス Test-key が関連づけられた CMK のキー ID を直接指定しても Deny されます。
% aws kms describe-key\ --key-id xxxxxxxx-e066-4bde-95e0-5ac3b2fb1d15 An error occurred (AccessDeniedException) when calling the DescribeKey operation: User: arn:aws:iam::000000000000:user/chiba-cli is not authorized to perform: kms:DescribeKey on resource: arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-e066-4bde-95e0-5ac3b2fb1d15 with an explicit deny
エイリアスベースの ABAC が確認できました。
ちなみに
今回のケースで、実行元の IAM ユーザーにProject
キーを持つタグが設定されていないと Deny が効きません。Project
キーの値がブランクな分には問題ない(エイリアス HOGEHOGE も含めて拒否される)のですが、キー自体が無いとそのような挙動となるようです。
${aws:PrincipalTag/xxx}
といったポリシー変数を条件キーに使用する際にはご注意ください。
ちなみに 2
エイリアス HOGEHOGE に加えて、エイリアス FUGAFUGA も関連づけた状態で試してみました。
エイリアス HOGEHOGE を指定した場合は変わらず成功します。
% aws kms describe-key\ --key-id alias/HOGEHOGE { "KeyMetadata": { "AWSAccountId": "000000000000", "KeyId": "xxxxxxxx-7f6d-4290-b6ff-182b2ae6dd6f", "Arn": "arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-7f6d-4290-b6ff-182b2ae6dd6f", "CreationDate": "2020-07-16T01:01:01.811000+09:00", "Enabled": true, "Description": "", "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "Origin": "AWS_KMS", "KeyManager": "CUSTOMER", "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT", "EncryptionAlgorithms": [ "SYMMETRIC_DEFAULT" ] } }
エイリアス FUGAFUGA を指定した場合は失敗します。
% aws kms describe-key\ --key-id alias/FUGAFUGA An error occurred (AccessDeniedException) when calling the DescribeKey operation: User: arn:aws:iam::000000000000:user/chiba-cli is not authorized to perform: kms:DescribeKey on resource: arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-7f6d-4290-b6ff-182b2ae6dd6f with an explicit deny
キー ID を直接指定した場合も失敗します。
% aws kms describe-key\ --key-id xxxxxxxx-7f6d-4290-b6ff-182b2ae6dd6f An error occurred (AccessDeniedException) when calling the DescribeKey operation: User: arn:aws:iam::000000000000:user/chiba-cli is not authorized to perform: kms:DescribeKey on resource: arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-7f6d-4290-b6ff-182b2ae6dd6f with an explicit deny
ややこしいですね。
終わりに
AWS KMS が タグもしくはエイリアスを使用した ABAC に対応したというアップデートでした。
適切に設定を行うことでセキュリティレベルを高めることができますね。一方で、タグやエイリアスの変更によって意図せず動作しなくなる、というリスクも抱えることになりますので、実装される際には検討・検証をしっかり行うようにしてください。
以上、千葉(幸)がお送りしました。