Amazon Web Services ブログ

AWS Key Management Serviceで権限委譲 (Grants) を付与してアクセス許可 (Permissions) を管理する

本記事は Managing permissions with grants in AWS Key Management Service を翻訳したものです。

本投稿は、AWS KMS チームの Software development engineer の Rick Yin により寄稿されました。

AWS Key Management Service (AWS KMS) は、お客様が暗号化を使用してデータを保護するのに役立ちます。Amazon Relational Database Service (Amazon RDS)Amazon Simple Storage Service (Amazon S3) バケットなど、暗号化された新しい Amazon Web Services (AWS) リソースを作成する場合、利用者が管理する AWS KMS キー ID を提供するだけでデータが暗号化され、暗号キーの保護と高可用性の実現の複雑さが軽減されます。

サービス内のデータを暗号化するときに、自分の管理下にあるキーを使用して、AWS サービスに暗号化を委任することを検討している場合、どのようにして AWS サービスがそのキーを必要なときにのみ使用し、すべてのリソースを復号するためのフルアクセスが常に許可されないようにしているのか疑問に思うかもしれません。その答えは、AWS KMS でスコープダウンされた動的なアクセス許可 (permissions) を使用することです。具体的には、KMS キーポリシードキュメントで定義したアクセス許可と、KMS 権限委譲 (grants) を使用して動的に作成される追加のアクセス許可の組み合わせによって、1 つ以上の AWS サービスが KMS キーを使用してデータを暗号化および復号する条件が定義されます。

このブログ記事では、以下について説明します。

  • AWS サービスが KMS キーポリシーと権限委譲を使用して、暗号化キーへのアクセスを安全に管理する方法の例
    この例では、Amazon RDS を使用し、データベースインスタンスの背後にあるブロックストレージボリュームがどのように暗号化されるかを示しています。
  • AWS KMS からの権限委譲を自分のワークロードで使用するためのベストプラクティス
  • AWS KMS で権限委譲を使用する際の最近のパフォーマンスの改善

ケーススタディ: RDS が AWS KMS からの権限委譲を使用してデータベースボリュームを暗号化する方法

多くの Amazon RDS インスタンスタイプは、 Amazon Elastic Compute Cloud (Amazon EC2) インスタンスでホストされ、基盤となるストレージレイヤーが Amazon Elastic Block Store (Amazon EBS) ボリュームです。データベースコンテンツを保存する EBS ボリュームのブロックは、ランダムに生成された 256 ビットの対称鍵のデータキーで暗号化されます。このデータキー自体は、データベースインスタンスの作成時に RDS が使用するように設定した KMS キーで暗号化されます。RDS が EBS、EC2、および AWS KMS とどのようにやり取りし、KMS キーを使用して RDS インスタンスを安全に作成するかを見てみましょう。

データベースを作成するために RDS にリクエストを送信すると、RDS、EC2、EBS、および KMS のサービス間で、次のような非同期リクエストが行われます。

  1. 一意の暗号化キーを使用して、基盤となるストレージボリュームを作成します。
  2. EC2 でコンピュートインスタンスを作成します。
  3. データベースエンジンを EC2 インスタンスにロードします。
  4. EC2 インスタンスに、暗号化キーを使用してデータベースのストレージボリュームにデータを読み書きするためのアクセス許可を与えます。

新しいデータベースを作成するための RDS に対するリクエストは、アカウントの AWS Identity and Access Management (IAM) プリンシパル (ユーザーやロールなど) によって最初に認証されます。リクエストを受信したら、次の一連の処理が行われます。

  1. RDS は、将来のデータを保存するために暗号化されたボリュームを作成するよう EBS に要求します。
  2. EBS は、AWS KMS がボリュームに対して一意の 256 ビットのデータキーを生成し、RDS で指定された KMS キーでそのデータキーを暗号化するよう要求します。
  3. RDS は、EC2 がインスタンスを起動し、暗号化されたボリュームをアタッチし、データキーを EC2 がボリュームへの読み取りと書き込みに使用できるようにすることを要求します。

利用者の観点からすると、データベースの作成に使用される IAM プリンシパルには、KMS キーポリシーで GenerateDataKeyWithoutPlaintext および Decrypt アクションのアクセス許可も必要です。これにより、KMS キーで一意の 256 ビットのデータキーが作成され暗号化できます。また、ユーザーまたはロールが、データキーを復号して EC2 インスタンスを管理する Nitro カードにプロビジョニングができるので、EC2 インスタンスがデータベースとの間で読み取りと書き込みを行うことができるようになります。データベースの作成プロセスとデータベースボリュームの起動プロセスの非同期性を考えると、RDS、EBS、および EC2 サービスはどのようにして必要な最小権限を取得するのでしょうか?この最小権限とはデータベースを使用するためにデータキーを作成してプロビジョニングするための権限委譲です。それでは、KMS キーポリシーで IAM プリンシパルに KMS CreateGrant アクションを許可することから始めます。

RDS は、IAM プリンシパルの ID を使用して AWS KMS で権限委譲を作成します。これにより、IAM プリンシパルが AWS KMS キーに対して持っている元のアクセス許可と比較して、非常に限定されたアクセス許可となる EC2 および EBS に対する他の権限委譲を作成できるようになります。この場合は、合計 3 つの権限委譲が作成されます。

  • 初期 RDS 権限委譲
  • 後続の EBS 権限委譲 、EBS が AWS KMS を呼び出し、データベースの作成時に定義した KMS キーで暗号化された 256 ビットのデータキーを生成できます。
  • アタッチメント権限委譲、これによりデータベースボリュームをホストしている特定の EC2 インスタンスが、暗号化されたデータキーを復号し、インスタンスと EBS ボリューム間の I/O 中に使用できるようにプロビジョニングできます。

RDS 権限委譲

この例では、ID が db-1234 となる RDS インスタンスを作成し、暗号化のための KMS キーを指定したとします。以下の権限委譲が KMS キーに作成され、RDS が EC2 と EBS に対して、データベースインスタンスの起動に必要な非同期プロセスで使用する権限委譲をさらに作成できるようにします。RDS 権限委譲は以下のとおりです。

{Grantee Principal: '<Regional RDS Service Account>', Encryption Context: '"aws:rds:db-id": "db-1234"', Operations: ['CreateGrant', 'Decrypt', 'GenerateDataKeyWithoutPlaintext']}

分かりやすく言えば、この権限委譲は、 Encryption Context パラメーターにある RDS インスタンス ID db-1234 が指定されている場合のみ、3 つの特定のオペレーション (API アクション) に KMS キーを使用するためのアクセス許可を RDS に付与します。この権限委譲は、<Regional RDS service account> に表示される被付与者プリンシパルにアクセスを提供します。この権限委譲は AWS KMS で作成され、KMS キーに関連付けられます。EC2 インスタンスはまだ作成および起動されていないため、被付与者プリンシパルには EC2 インスタンス ID を含めることはできず、代わりに各リージョンの RDS サービスアカウントである必要があります。

EBS 権限委譲

RDS インスタンスと初期 AWS KMS 権限委譲が作成されると、RDS は EC2 に RDS データベースのインスタンスを起動するようリクエストします。EC2 は、元の IAM プリンシパルに付与した EC2 アクセス許可を使用して、一意の ID (i-1234567890abcdefg など) を持つインスタンスを作成します。EC2 インスタンスの作成に加えて、RDS は Amazon EBS に、データベース専用の暗号化されたボリュームを作成することを要求します。ボリューム作成時には、EBS はボリューム暗号化用の 256 ビットデータキーを生成し、事前に定義された KMS キーでそのデーターキーを暗号化するためのアクセス許可を必要とします。

EC2 インスタンス ID は、AWS KMS への今後の呼び出しで ID の名前として使用されるため、RDS はそれを作成する EBS 権限委譲の被付与者プリンシパルとして、この ID を挿入します。EBS 権限委譲は次のとおりです。

{Grantee Principal: '<RDS-Host-Role>:i-1234567890abcdefg', Encryption Context: '"aws:rds:db-id": "db-1234"', Operations: ['CreateGrant', 'Decrypt', 'GenerateDataKeyWithoutPlaintext']}}

この権限委譲では、初期 RDS 権限委譲と同じ暗号化コンテキストが使用されていることがわかるでしょう。ただし、EC2 インスタンス ID がデータベース ID に関連付けられるようになったので、EBS がキーを被付与者プリンシパルとして使用するために取得する権限委譲をスコープダウンして、両方の値を要求できるようになりました。この権限委譲が作成されると、EBS は EBS ボリューム( vol-0987654321gfedcba など) を作成し、AWS KMS を呼び出して、そのボリュームでのみ使用できる 256 ビットのデータキーを生成して暗号化できます。この暗号化されたデータキーは、ボリュームアタッチプロセスの準備として EBS によって保存されます。

アタッチメント権限委譲

RDS インスタンスを作成する最後のステップは、データベースをホストする EC2 インスタンスに EBS ボリュームをアタッチすることです。EC2 は、以前に作成した EBS 権限委譲を使用して、i-1234567890abcdefg のインスタンス ID を持つアタッチメント権限委譲を作成するようになりました。この権限委譲により、EC2 は暗号化されたデータキーを復号し、インスタンスを管理する Nitro カードにプロビジョニングして、RDS データベースの EBS ボリュームへの I/O の暗号化を開始できます。この例のアタッチメント権限委譲は、次のようになります。

{Grantee Principal: 'EC2 Instance Role:i-1234567890abcdefg', Encryption Context: '"aws:rds:db-id": "db-1234", "aws:ebs:id":"vol-0987654321gfedcba"', Operations: ['Decrypt']}

アタッチメント権限委譲は、3 つの権限委譲の中で最も制限の厳しいものです。呼び出し側は、関連するすべての AWS エンティティ (EC2 インスタンス ID、EBS ボリューム ID、RDS データベース ID) の ID を知っている必要があります。この設計により、KMS キーは、必要な特定の RDS データベースを起動するために、これらの AWS サービスによる復号にのみ使用できるようになります。

暗号化された EBS ボリュームがアクティブになり、EC2 インスタンスにアタッチされました。RDS インスタンスを終了すると、関連するすべての KMS 権限委譲がサービスによって取り消されるため、KMS キーを使用して、データベース内のデータを復号するのに必要な 256 ビットのデータキーを復号する権限委譲がなくなります。暗号化されたデータベースを再度起動する必要がある場合は、AWS KMS キーに対するアクセス許可のスコープダウンに使用される RDS データベース、EC2 インスタンス、および EBS ボリューム ID を使用して、同様の 3 つの権限委譲のセットが動的に作成されます。

前の段落で説明したプロセスを図 1 に示します。

Figure 1: How Amazon RDS uses Amazon EC2, Amazon EBS, and AWS KMS to create an encrypted RDS instance

データベースの起動の一環として追加および削除される AWS KMS のキーへのアクセス許可を考慮する場合、キーポリシードキュメントを使用してこれらの変更を行わない理由を尋ねられるかもしれません。 KMS キーは、最大ドキュメントサイズが 32 KB のキーポリシーを 1 つだけ作成できます。1 つのキーを使用して任意の数の AWS リソースを暗号化できるため、各リソースに関連するスコープダウンされたアクセス許可をキーポリシードキュメントに動的に追加および削除しようとすると、2 つのリスクが生じます。1 点目は、キーポリシードキュメントの最大許容サイズ (32 KB) を超えることがあります。2 点目は、同時にアクセスされるリソースの数によっては、AWS KMS の PutKeyPolicy API アクションのリクエストレートがクォータを超える可能性があります。

対照的に、特定の AWS KMS キーにはいくつでも権限委譲があります。各権限委譲では、AWS KMS と統合されたすべての AWS サービスで KMS キーを使用するためのスコープダウンされたアクセス許可を指定します。また、権限委譲の作成と削除は、キーポリシードキュメントに対する変更よりも大量のリクエストレートに対応するように設計されています。最後に、PutKeyPolicy を呼び出すアクセス許可は非常に特権的なパーミッションです。これにより、キーの無効化や削除のスケジュールを設定するための管理者の許可の変更などのキーへのアクセス許可を無制限に変更できます。キーに対する権限委譲は、キーを使用するためのアクセス許可のみ与え、キーの管理は許可しません。また、他の IAM プリンシパルによる追加の権限委譲の作成を許可する権限委譲では、特権の昇格は禁止されています。上記の RDS の例では、最初の CreateGrant リクエスト中に RDS がアカウントの IAM プリンシパルから受け取るアクセス許可は、KMS キーポリシーで IAM プリンシパルに定義したものよりも許可の度合いが高くなることはありません。データベース作成プロセス中に RDS が EC2 と EBS に付与するアクセス許可は、RDS が最初の権限委譲で付与された元のアクセス許可よりも寛容にすることはできません。この設計により、AWS のサービスが特権に昇格したり、意図した目的と異なる目的で KMS キーを使用したりすることがなくなります。

AWS KMS 権限委譲の使用に関するベストプラクティス

AWS KMS の権限委譲は、キーを使用するアクセス許可を動的に定義する強力なツールです。さまざまな AWS サービスでサーバー側の暗号化機能を使用すると、自動的に作成されます。また、権限委譲を使用して、クライアント側の暗号化を実行する独自のアプリケーションのアクセス許可を制御することもできます。考慮すべきベストプラクティスをいくつか挙げます。

  • 可能な限りスコープを絞ってアクセス許可を設計します。IAM ロールなどの特定の被付与者プリンシパルを使用し、必要な AWS KMS API アクションへのアクセスのみをプリンシパルに付与します。呼び出し元が AWS KMS キーを意図した目的にのみ使用するようにするには、任意の要素を使用することで Encryption Context パラメータを使用して権限委譲の範囲をさらに制限できるようになります。以下は、GenerateDataKey または Decrypt を呼び出すアクセス許可を AWS アカウント 123456789012 に付与する具体的な例です。ただし、暗号化コンテキストとして customerID5678 が指定されている場合に限ります。
    {Actions: 'GenerateDataKey, Decrypt', Grantee Principal: '123456789012', Encryption Context: '"customerID": "5678"'}
    

    この権限委譲により、AWS KMS へのリクエストに想定される customerID が明示的に含まれていなければ、カスタマー「5678」に属するデータをアプリケーションが復号できないことになります。これは、アプリケーションの AWS 認証情報が侵害され、暗号化と復号のためにすべての読み取りと書き込みに暗号化コンテキストが必須のパラメータであることを知らない別の呼び出し元から使用された場合に、顧客のデータへの不正アクセスを防ぐための多層防御メカニズムになり得ます。

    AWS KMS のアクセス許可やリクエストにより暗号化コンテキストを使用する方法や AWS CloudTrail ログの詳細については、 ブログ記事 「How to Protect the Integrity of Your Encrypted Data by Using AWS Key Management Service and EncryptionContext (日本語訳:AWS Key Management ServiceとEncryptionContextを利用して暗号化データの完全性を保護する方法)」を参照してください。

  • 権限委譲は自動的には期限切れにならないことに注意してください。KMS キーに対する権限委譲が不要になったら、コードを廃止するか、取り消す必要があります。廃止されない権限委譲は、暗号化されたリソースのセキュリティリスクを引き起こす可能性があるアクセス許可となります。詳細については、AWS KMS 開発者ガイドの「権限の使用停止と取り消し」を参照してください。
  • 重複した権限委譲の作成は避けてください。重複した権限委譲とは、同じ AWS KMS キー ID、API アクション、被付与者プリンシパル、暗号化コンテキスト、および名前を共有する権限委譲です。もし使用後にオリジナルの権限委譲を廃止しても、重複した権限委譲が残っていると、データの暗号化または復号に意図しないアクセスが発生する可能性があります。

AWS KMS 権限の最近のパフォーマンス向上:リソースクォータの削除

お客様が AWS KMS の権限委譲を使用して AWS サービスのリソースを暗号化する場合、同じ KMS キーで暗号化できる同時アクティブなリソースの数に、かつてはクォータが適用されました。たとえば、非常に大規模に Amazon RDS、Amazon WorkSpaces、Amazon EBS 等をお使いのお客様は、このクォータに達したことがあるでしょう。このクォータは「特定のプリンシパルに対する KMS キーあたりの権限委譲」であり、以前は 500 に設定されていました。これらのサービスのいずれかでリソースを作成しようとすると、「このリージョンでは、被付与者プリンシパルあたり 500 個の権限委譲しかサポートしていません  (“Keys only support 500 grants per grantee principal in this region”) 」というエラーメッセージが表示されることがありました。

最近、AWS KMS に変更を加え、このクォータを完全に削除したため、このエラーメッセージはなくなりました。このクォータが削除されたことで、どのAWSサービスを使用しても、どのKMSキーにも無制限の権限委譲をアタッチできるようになりました。

まとめ

このブログ投稿では、 Amazon RDS などのサービスが AWS KMS の権限委譲を使用して、Amazon EC2Amazon EBS を通じてスコープダウンされたアクセス許可を渡す方法を見てきました。また、AWS KMS 権限委譲を独自のアプリケーションで使用するためのベストプラクティスもいくつか見ました。最後に、リソースクォータの 1 つが削除されたことによって AWS KMS のパフォーマンスが改善されたことを学びました。

AWS KMS と権限委譲に関する追加リソースを以下に示します。

翻訳は Solutions Architect の岡本真樹が担当しました。原文はこちらです。