Amazon SCS-C02: 暗号化、KMS、シークレット — 学習ガイド
こちらの一部です: AWS Security Specialty SCS-C02 — 学習ガイド. 検証済みの解答で練習: Amazon試験ハブ, または時間制限付き模擬試験に挑戦: ExamRoll.io.
AWS KMS のキータイプ、ポリシー、アクセスコントロール
AWS KMS は、大きく分けて3つのカテゴリのキーをサポートしており、どのキーを選択するかによって、キーマテリアルの管理者、保管場所、ローテーション方法が決まります。AWS 所有のキーはユーザーには見えず、コストもかからず、SSE-S3 を有効にした場合に S3 などのサービスによって使用されます。AWS マネージドキー (エイリアスは aws/<service>) を使用すると、サービスがユーザーに代わって暗号化を行いますが、キーポリシーを変更することはできません。そのため、クロスアカウントアクセスやきめ細かなガバナンスには不向きです。カスタマー管理型キー (CMK) は主力となるキーです。キーポリシー、ローテーション (年1回の自動またはオンデマンド)、グラント、エイリアス、削除猶予期間をユーザーが管理します。
特殊なバリエーションとして、2つの重要なものがあります。インポートされたキーマテリアルは、規制や BYOK (Bring Your Own Key) 要件により、AWS の外部でキーマテリアルを生成し、それを KMS キーにインポートする必要がある場合に使用されます。インポートされたマテリアルは、キーマテリアルの明示的な有効期限を設定できる唯一の方法です。AWS が生成した CMK には有効期限がありません。インポートされたキーでは、AWS の年1回の自動ローテーションを有効にすることはできず、自身でマテリアルを再インポートする必要があります。マルチリージョンキーは、レプリカキーを介してリージョン間で同じキー ID とマテリアルを共有するため、us-east-1 で生成された暗号文を us-west-1 で再暗号化することなく復号できます。各レプリカは独立したキーポリシーとエイリアスを持ちますが、暗号化マテリアルは同期されます。
最も誤解されがちな制御が KMS キーポリシーです。IAM ポリシーだけでアクセスを許可するほとんどの AWS リソースとは異なり、KMS キーはそのキーポリシーを認可の基点として使用します。あるキーに対する kms:Decrypt を許可する IAM ポリシーは、キーポリシーが (アカウントルートの Principal と適切なステートメントを介して、またはプリンシパルを直接指定して) IAM へのアクセスを委任していない限り、効果がありません。これが、AdministratorAccess を持つエンジニアであっても、アカウントを信頼していないポリシーを持つ CMKに対して Decrypt を呼び出すと AccessDenied を受け取ることがある理由です。標準的な委任ステートメントは次のようになります。
{
"Sid": "EnableIAMPermissions",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:root" },
"Action": "kms:*",
"Resource": "*"
}
グラントや ViaService 条件は、階層的な制約を追加します。例えば、kms:ViaService: s3.us-east-1.amazonaws.com を使用して、特定のリージョンの S3 を介してのみキーが使用されるように強制することができます。
サーバー側の暗号化とクライアント側の暗号化
S3 の場合、一般的な2つのサーバー側オプションは、主に管理と監査の可能性において異なります。
- SSE-S3 (AES-256): S3 がキーを完全に管理します。ユーザーが参照できるキーポリシーはなく、キーごとの CloudTrail 復号イベントもなく、クロスアカウントのガバナンスもありません。保管時の基本的な暗号化には十分ですが、コンプライアンス要件で誰がデータを復号したかを証明する必要がある場合には不十分です。
- SSE-KMS: ユーザーが管理する CMK を使用します。すべての復号呼び出しがログに記録され、キーポリシーによってアクセスが強制され、暗号化コンテキストによって制限することができます。リクエストあたりのコストが高く、KMS の TPS クォータを消費するため、バケットキー (
BucketKeyEnabled: true) を有効にして KMS の呼び出しを劇的に削減すべきです。
AWS Encryption SDK を使用したクライアント側の暗号化は、データがアプリケーションを離れる前に暗号化する必要がある場合や、ストレージサービスが平文を決して見てはならない場合に適しています。高スループットのワークロードでは、SDK をキャッシング暗号化マテリアルマネージャー (CachingCryptoMaterialsManager) でラップする必要があります。これにより、設定可能なバイト数、メッセージ数、TTL の制限内で、多くのメッセージにわたってデータキーが再利用されます。キャッシングを行わないと、encrypt を呼び出すたびに GenerateDataKey リクエストがトリガーされ、KMS のリクエストクォータをすぐに飽和させ、コストを増大させます。
from aws_encryption_sdk import CachingCryptoMaterialsManager, LocalCryptoMaterialsCache
cache = LocalCryptoMaterialsCache(capacity=100)
ccmm = CachingCryptoMaterialsManager(
master_key_provider=mkp, cache=cache,
max_age=600.0, max_messages_encrypted=10000)
Secrets Manager と Parameter Store
Secrets Manager は、KMS CMK で暗号化された認証情報を保存し、Lambda 関数による自動ローテーションをサポートします。AWS は RDS、Redshift、DocumentDB 用のテンプレートを提供しており、カスタム Lambda でそれ以外のものも処理できます。ローテーションは4段階のステートマシン (createSecret, setSecret, testSecret, finishSecret) を実行し、新しい認証情報を AWSCURRENT に昇格させる前に AWSPENDING ラベルでステージングします。アプリケーションは認証失敗をキャッチし、シークレットを更新して再試行すべきです。このパターンにより、以前の認証情報が AWSPREVIOUS を介して短時間有効なままであるため、ダウンタイムが排除されます。
ローテーション用の Lambda が VPC 内で実行される場合 (プライベートな RDS インスタンスにアクセスする典型的なケース)、Secrets Manager サービスエンドポイントへのアウトバウンドネットワークアクセスが必要です。NAT のないプライベート VPC では、インターフェイス VPC エンドポイント (com.amazonaws.<region>.secretsmanager) をデプロイし、Lambda のセキュリティグループがポート 443 でエンドポイントに到達することを許可する必要があります。これを忘れるのは典型的な失敗パターンです。ローテーションは設定されているように見えますが、すべての呼び出しがタイムアウトします。
クロスリージョンでの回復性のために、マルチリージョン KMS キーと Secrets Manager のレプリカシークレット機能を使用します。us-east-1 のプライマリシークレットはプライマリ CMK で暗号化され、us-west-1 のレプリカはレプリカ CMK を使用して復号します。alias/prod-db のようなエイリアスは、アプリケーションコードを変更することなく、迅速なキーローテーションのためにオンデマンドで新しいキー ID に向けることができます。
Parameter Store の SecureString タイプは、ローテーションが不要な場合の軽量な代替手段です。どちらのサービスも、CloudFormation で動的参照 ({{resolve:secretsmanager:MySecret:SecretString:password}}) を公開しているため、スタックテンプレートに平文が埋め込まれることがなくなります。
EBS、RDS、Aurora、およびスナップショットの暗号化
保管時の暗号化は、作成時にボリュームごとまたはインスタンスごとに有効になり、後から切り替えることはできません。コンプライアンスに準拠していない暗号化されていないリソースの修正パターンは、暗号化を有効にしたスナップショットのコピーです。
aws ec2 copy-snapshot --source-snapshot-id snap-abc \
--source-region us-east-1 --encrypted \
--kms-key-id alias/prod-ebs
aws ec2 create-volume --snapshot-id snap-newEncrypted ...
RDS と Aurora の場合、暗号化されたスナップショットを新しいインスタンスに復元し、切り替えます。クロスアカウントでの復旧には、スナップショットの共有および、キーポリシーを介して宛先アカウントに CMK に対する kms:CreateGrant と kms:Decrypt を許可する必要があります。スナップショットを共有するだけでは、宛先アカウントがデータキーを復号できないため失敗します。アカウントレベルの EBS デフォルト暗号化を有効にすると、呼び出し元の動作に関係なく、新しく作成されるボリュームは常に暗号化されます。
TLS: ACMとALBポリシー
ACMは、統合サービス(ALB、CloudFront、API Gateway)にバインドされると、パブリック証明書を無料で発行し、自動更新します。証明書はエクスポートできないため、EC2でTLSを終端するには、ACM Private CA(エクスポート可能なプライベート証明書用)またはインポートされた証明書のいずれかが必要です。実用的なパターンとして、ALBでACM証明書を使用してパブリックTLSを終端し、エンドツーエンドの暗号化が必要な場合は、ALBからEC2へのホップに自己署名証明書またはプライベートCA証明書を使用します。ELBSecurityPolicy-TLS13-1-2-2021-06のようなセキュリティポリシーを使用して、クライアントに最新の暗号スイートの使用を強制します。このポリシーはTLS 1.0/1.1と脆弱なスイートを無効化します。
よくある落とし穴
キーポリシーなしのIAM。 CMKのキーポリシーがアカウントプリンシパルを省略している状態で、IAMポリシーでkms:Decryptを許可すると、AccessDeniedが発生します。KMSはキーポリシーを権威あるものとして扱います。IAMのアクセス許可は、キーポリシーが許可する内容をさらに制限することしかできません。
VPCエンドポイントなしのローテーション用Lambda。 Lambdaがプライベートサブネットで実行され、VPCにNATがなく、secretsmanagerインターフェイスエンドポイントもない場合、secretsmanager.<region>.amazonaws.comへのローテーション呼び出しは名前解決も接続もできません。また、エンドポイントのセキュリティグループは、LambdaのSGからの443を許可する必要があります。
SSE-S3とSSE-KMSの混同。 SSE-S3はAWS所有のキーを使用し、顧客が編集可能なポリシーはなく、CloudTrailでのオブジェクトごとの復号ログもなく、アカウント間でのキー共有もできません。これは「保管時の暗号化」のチェックボックスを満たしますが、どのプリンシパルが特定のオブジェクトを復号できるかを強制することはできません。そのガバナンスを提供するのは、CMKを使用したSSE-KMSだけです。
実践的な問題: ユースケースシナリオ
シナリオ: Meridian Financialは、セキュリティアカウント、本番/非本番の個別アカウント、ECS/EKS内のALBをフロントにしたマイクロサービス、RDS/Auroraクラスター、EBSをバックエンドとするEC2インスタンス、S3データレイクを持つマルチアカウントのAWS Organizationを運営しています。開発者と自動化は現在、AWSマネージドキー、平文のSSMパラメータ、およびアカウント間での時折の手動スナップショット共有を混在して使用しています。
課題: あるエンジニアが誤って暗号化されていないRDSスナップショットをサードパーティのアカウントと共有し、いくつかのAPI認証情報が平文のSecureStringパラメータとして保存されていることが発見されました。これにより、データ漏洩と不正なリストアアクセスのリスクが生じています。
推奨アプローチ:
- セキュリティアカウントに、組織スコープのカスタマーマネージドAWS KMS対称CMKを作成し、
aws:PrincipalOrgIDを介してメンバーアカウントに使用を許可するキーポリシーを設定し、自動ローテーションを有効にします。短期的なクロスアカウント操作にはグラントを使用します。 - 暗号化されていないRDSスナップショットと任意のEBSスナップショットをコピーする際に新しいCMKを選択して暗号化されたコピーを作成し、元の暗号化されていないスナップショットを削除することで、既存のアーティファクトを修正します。アカウントのデフォルト設定で、新しいRDSとEBSがデフォルトで暗号化リソースを作成するようにします。
- シークレットをCMKで暗号化されたAWS Secrets Manager(またはSSM Parameter Store SecureString)に移行し、Lambdaを介してDB認証情報のSecrets Manager自動ローテーションを有効にし、リソースベースのポリシーと最小権限のIAMロールを使用してアクセスを制限します。
- ACMで管理されたTLS証明書をプロビジョニングし、最新のTLSポリシー(TLS 1.2/1.3)でALBにアタッチすることで、転送中の暗号化を強制します。また、データベースとクライアントがTLS接続を要求するように設定します。
- ガードレールで再発を防止します。Service Control Policiesを適用して、暗号化されていないスナップショットの作成/共有や暗号化されていないS3へのputを拒否し、暗号化リソースに対するAWS Configルールを有効にし、CloudTrailとCloudWatch Alarmsを介してKMSとSecrets Managerの使用状況を監視します。
論理的根拠: 組織レベルのポリシーを持つ中央CMK、自動再暗号化、シークレットライフサイクル管理のためのSecrets Manager、TLSの強制、および予防的なガードレールは、AWSの最小権限と多層防御のベストプラクティスに従い、平文のシークレットと不正なスナップショットアクセスを排除します。
カスタマー管理CMK: マルチリージョン、インポートされたマテリアル、キーポリシー
カスタマー管理CMKは、AWSでお客様が所有するデータに対するすべての暗号化オペレーションのコントロールプレーンです。設計が成功するか、あるいは障害を引き起こすかを最も頻繁に決定づける3つのプロパティは、キーのリージョントポロジー、キーマテリアルのオリジン、そしてキーにアタッチされたポリシーです。
マルチリージョンキーは、異なるリージョンにあるKMSキーのセットであり、同じキーID、そして決定的に重要な点として、同じ基盤となるキーマテリアルを共有します。DynamoDBグローバルテーブルのように自動的にレプリケートされるわけではなく、ReplicateKeyを使用してプライマリキーから明示的にレプリカを作成します。キーマテリアルはレプリカ間で同一であるため、us-east-1で生成された暗号文は、リージョン間のKMSコールなしでus-west-1で復号できます。これは、Secrets Managerのシークレットをリージョン間でレプリケートする際にまさに必要とされるプロパティです。フェイルオーバーリージョンのレプリカシークレットは、すべてのGetSecretValueにおけるリージョン間のレイテンシーを排除し、かつプライマリのリージョン障害を乗り切るために、ローカルで復号可能でなければなりません。シングルリージョンCMKは、他のリージョンにあるSecrets Managerのレプリカをサポートできません。したがって、正しいパターンは、プライマリシークレットをマルチリージョンCMKで暗号化し、キーを宛先リージョンにレプリケートし、その後レプリカCMKを指定してシークレットをレプリケートすることです。
aws kms create-key --multi-region --region us-east-1
aws kms replicate-key --key-id mrk-abc123 \
--replica-region us-west-1
aws secretsmanager replicate-secret-to-regions \
--secret-id prod/db \
--add-replica-regions Region=us-west-1,KmsKeyId=mrk-abc123
インポートされたキーマテリアル(外部オリジン、Origin=EXTERNAL)は、AWSの外部で生のAES-256マテリアルを生成し、それをKMSキーのシェルにインポートする場合に存在します。AWSは、HSMの保護されたメモリの外ではそのマテリアルのコピーを保持せず、バックアップも存在しません。DeleteImportedKeyMaterial経由であれ、有効期限が切れたためであれ、インポートされたマテリアルを削除すると、キーはPendingImport状態になり、そのキーで生成されたすべての暗号文は、全く同じバイトを再インポートしない限り復旧不能になります。これは、例えば、暗号化されたデータキーが復号できないためにEBSボリュームのアタッチに失敗した場合の回復パスです。オフラインのエスクローから同一のキーマテリアルを再インポートすれば、ボリュームは再び使用可能になります。AWS側でのリストア、ローテーションの裏技、削除されたインポート済みマテリアルを回復させるサポートチケットは存在しません。オフラインのコピーは、ティアゼロのインフラストラクチャとして扱ってください。
キーポリシーは、すべてのKMSキーにおける信頼の基点(ルート・オブ・トラスト)です。IAM単独とは異なり、KMSはキーポリシー自体での明示的な許可を必要とします。kms:Decryptを許可するIAMポリシーは、キーポリシーがIAMに委任(条件ステートメントと組み合わせた "Principal": {"AWS": "arn:aws:iam::111122223333:root"})しない限り、効果がありません。クロスアカウントでの使用の場合、キーのポリシーで外部アカウントまたはプリンシパルを明示的に指定する必要があり、その後、外部アカウントがIAMを介して自身のユーザーに権限を付与する必要があります。キーポリシー側を忘れることは、クロスアカウントでのSecrets Managerの失敗の最も一般的な原因です。Secrets Managerのリソースポリシーは外部プリンシパルによるGetSecretValueの呼び出しを許可しますが、CMKが依然として呼び出し元を拒否するため、基盤となるDecryptが失敗します。
Secrets ManagerとParameter Store SecureStringのパターン
Secrets ManagerとSSM Parameter StoreのSecureStringはどちらも暗号化をKMSに委任しますが、コスト、ローテーションのセマンティクス、クロスリージョンの動作において異なります。Secrets Managerは、ネイティブなマルチリージョンレプリケーション、ステージングラベル(AWSCURRENT、AWSPENDING)によるバージョニング、およびLambdaによるローテーションをサポートしています。Parameter StoreのSecureStringはより安価で、階層的なパスと統合でき、ローテーション頻度の低い設定スタイルのシークレットに適しています。
クロスアカウントアクセスのためには、シークレットのリソースポリシー(またはParameter StoreのコンシューマーアカウントのIAMポリシー)と、暗号化CMKのKMSキーポリシーの両方を更新する必要があります。Secrets Managerの権限だけで十分だと考えるのは間違いです。なぜなら、取得ワークフローは常にCMKに対して暗黙的なkms:Decryptを実行するからです。外部アカウントに対するキーポリシーの許可がない場合、シークレット自体のポリシーが満たされていても、呼び出し元はDecryptステップでAccessDeniedExceptionを受け取ります。
- Secrets Manager: マネージド型のローテーション、JSON構造、シークレットあたり月額約$0.40、マルチリージョンレプリケーションが組み込み
- Parameter Store SecureString (Advanced): 多数の値に対してより安価、パラメータあたり8 KB、組み込みのクロスリージョンレプリケーションなし
- Parameter Store SecureString (Standard): 4 KBまでのKMS暗号化パラメータに対する無料利用枠、ローテーションのフレームワークなし
エンベロープ暗号化、バケットキー、グラントトークン
エンベロープ暗号化では、KMSがバルクデータに直接触れることはありません。GenerateDataKeyを呼び出すと、平文のデータキー(ペイロードをAES-GCMでローカルに暗号化するために使用)と、そのデータキーの暗号化されたコピー(暗号文と一緒に保存)の両方が返されます。復号するには、ラップされたデータキーに対してDecryptを呼び出し、ローカルで平文キーを再導出します。KMSにはリクエストクォータ(リージョンごと、キーごと)とAPIコールごとの料金設定があるため、このパターンは不可欠です。4KBの各レコードを直接Encryptコールで暗号化すると、スロットリングやコストの急増に直面します。バッチごとやファイルごとに1つのデータキーを生成すれば、スループットはローカルの暗号化ライブラリに比例してスケールします。
S3 Bucket Keysは、SSE-KMSのためにS3内部で同じ原則を適用します。バケットキーがない場合、SSE-KMSオブジェクトのすべてのPUTおよびGETリクエストがGenerateDataKeyまたはDecryptコールを生成します。毎秒数千のオブジェクトを受信するバケットでは、これによりKMSのスロットリングと想定外のKMS請求額の両方が発生します。バケットキーを有効にすると、S3はバケットレベルで短命なキーを1つ生成し、それを多くのオブジェクトで再利用するため、KMSリクエスト量が桁違いに削減されます。
aws s3api put-bucket-encryption --bucket app-data \
--server-side-encryption-configuration '{
"Rules":[{
"ApplyServerSideEncryptionByDefault":{
"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/app"},
"BucketKeyEnabled":true}]}'
グラントは、一時的で詳細な権限委譲を行うためのキーポリシーの代替手段です。運用上重要なのは、結果整合性のためです。CreateGrantが返された後、グラントはリージョン内のすべてのKMSエンドポイントに即座には可視になりません。クライアントが数ミリ秒後にEncryptを試みると、AccessDeniedExceptionを受け取る可能性があります。CreateGrantのレスポンスボディにはGrantToken文字列が含まれており、これを後続のKMSコールで--grant-tokensパラメータを介して渡すと、KMSは伝播状態に関係なく即座にそのグラントを有効にします。
TOKEN=$(aws kms create-grant --key-id $KEY \
--grantee-principal arn:aws:iam::111122223333:role/worker \
--operations Encrypt Decrypt --query GrantToken --output text)
aws kms encrypt --key-id $KEY --plaintext fileb://payload \
--grant-tokens "$TOKEN"
グラントトークンの代わりにリトライとバックオフに頼ることは、有効ではあるものの劣った緩和策です。レイテンシーを浪費し、高負荷時には依然として失敗する可能性があります。規範的な答えは常にこれです:グラントを作成するサービスからグラントトークンを返し、呼び出し元に最初のオペレーションでそれを提示させることです。
実践的な問題:ユースケースシナリオ
シナリオ: Meridian Financial社は、マルチアカウントのAWS環境を運用しており、S3に顧客のPII(個人を特定できる情報)、RDSにトランザクションデータベース、Lambdaでサーバーレス処理をホストしています。同社は、地域のキー保管規則を満たすためにインポートされたキーマテリアルを持つカスタマー管理型のCMKを使用し、ディザスタリカバリのためにキーをセカンドリージョンにレプリケートしています。
課題: 最近の監査で、クロスアカウントでの復号を許可するKMSキーポリシーの設定ミスが発見されました。また、外部の監査人がS3オブジェクトのサブセットを復号するための一時的なアクセスを必要としています。さらに、Meridian社は、KMSリクエストコストを管理するために、安全なシークレットのローテーションと、大きなオブジェクトに対する効率的な暗号化を必要としています。
推奨アプローチ:
- AWS KMSで設定ミスのあるCMKのポリシーを、必要なIAMプリンシパルとロールのみを明示的に許可する最小権限のポリシーに置き換え、KMSのマルチリージョンキーを使用してDR用のマルチリージョンレプリカCMKを作成します。
- コンプライアンス期間に従ってインポートされたキーマテリアルを再インポートするか、ライフサイクル管理をスケジュールし、AWS ConfigとEventBridgeを使用してキーマテリアルの有効期限切れ/ローテーションの自動通知を有効にします。
- 監査人のためには、短いTTLを持つKMSグラントを作成し、監査人のassume-roleセッションで即座にグラントトークンを使用して、キーポリシーを変更することなく一時的な復号オペレーションを許可します。
- 長期的な認証情報をAWS Secrets Managerに移行し、基盤となるサービス(RDSやAPIキー)に連携したLambdaベースのローテーションを設定します。ローテーションしない項目については、インフラストラクチャパラメータをSystems Manager Parameter StoreのSecureStringとして保存し、CMKによる暗号化と厳格なリソースベースのポリシーを強制します。
- アプリケーションコード内またはAWS SDK経由でKMSの
GenerateDataKey(Encrypt/Decrypt)を呼び出すことにより、大きなS3オブジェクトに対してエンベロープ暗号化を実装します。また、S3 Bucket Keysを有効にして、大きなオブジェクトのサーバーサイド暗号化におけるKMSリクエストとコストを削減します。 - CloudTrailロギングとKMSキー使用状況のロギングを有効にし、予期しない復号やグラント作成についてアラートを出すためのCloudWatch Alarms/GuardDutyルールを作成します。
アプローチの根拠: このアプローチは、最小権限のキーアクセスを強制し、インポートされたマテリアルのコンプライアンスとマルチリージョンの継続性を維持します。また、安全なサードパーティアクセスのために一時的なグラントを使用し、ローテーションを伴うシークレットの一元管理を行い、AWSのベストプラクティスに従ってKMSの使用量とコストを最適化します。
← ロギング、監査、フォレンジック · すべてのドメイン · データ保護とS3 →
これらの問題を練習する → · ExamRoll.ioで時間制限付き練習 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
試験に合格する →