機密情報を安全に扱う ― 暗号化キー管理・シークレット保管・自動ローテーション・アプリからの参照
パスワードや API キーをコードに直接書くのは重大なセキュリティリスクです。このハンズオンでは、AWS KMS で暗号化キーを管理し、Secrets Manager でシークレットを安全に保管・自動ローテーションし、アプリケーションから安全に参照する流れを実践します。
| 項目 | 内容 |
|---|---|
| 対象サービス | AWS KMS、AWS Secrets Manager、S3、CloudTrail、Lambda |
| 主な学習内容 | カスタマーキー / キーポリシー / SSE-KMS / シークレット保管 / 自動ローテーション / アプリ参照 |
| 所要時間 | 60〜75 分 |
| 難易度 | ★★★☆☆(中級者向け) |
| 前提知識 | IAM の基礎・暗号化の概念・JSON の読み書き |
| 費用目安 | 約 1 USD(KMS キー 1 USD/月 + シークレット 0.40 USD/月。日割りで少額) |
| サービス | 役割 |
|---|---|
| KMS | 暗号化キーそのものを管理。他サービスのデータを暗号化する「鍵」 |
| Secrets Manager | パスワード等の「値」を KMS で暗号化して保管・ローテーション |
handson-keyhandson/db-credentialsKMS の Decrypt や Secrets Manager の GetSecretValue はすべて CloudTrail に記録され、「いつ・誰が・どの鍵で復号したか」を監査できます。
ap-northeast-1(東京) を使用aws CLI / python3 + boto3 が使える環境(CloudShell 推奨)「KMS(Key Management Service)」→「キーの作成」 をクリックします。
| 設定項目 | 設定値 |
|---|---|
| キーのタイプ | 対称(Symmetric) |
| キーの使用法 | 暗号化および復号 |
| エイリアス | handson-key |
「キー管理者」に自分の IAM ユーザー / ロールを、「このキーを使用できる AWS アカウントとユーザー」に利用するロールを指定します。これが キーポリシー として保存されます。
KMS では、IAM ポリシーだけでなく キーポリシー でも明示的に許可されている必要があります。キーポリシーに記載のないプリンシパルは、IAM で許可されていても使えません。
作成後、キーの詳細「キーのローテーション」タブで 「自動キーローテーション」 を有効にします(年 1 回、AWS が自動でキーマテリアルを更新。アプリ側の変更は不要)。
カスタマー管理型キー一覧に handson-key が「有効」で表示され、キー ARN が確認できれば成功です。
S3 バケット handson-kms-xxxx を作成し、「プロパティ」→「デフォルトの暗号化」→「編集」で以下を設定します。
レスポンスに "ServerSideEncryption": "aws:kms" と KMS キー ARN が表示されれば、KMS で暗号化されています。
オブジェクトをダウンロードすると、KMS の Decrypt API が呼ばれます。「CloudTrail」→「イベント履歴」 でイベント名 Decrypt を検索すると、誰がいつ復号したかが記録されています。
オブジェクトが aws:kms で暗号化され、ダウンロード時に CloudTrail に Decrypt が記録されれば成功です。キーへのアクセス権がないユーザーはダウンロードできません。
「Secrets Manager」→「新しいシークレットを保存する」 をクリックします。
キー / 値のペアで以下を入力します。
{
"username": "appuser",
"password": "InitialP@ssw0rd!",
"host": "handson-rds.xxxx.ap-northeast-1.rds.amazonaws.com",
"dbname": "handson_db"
}
「次へ」を進めて保存します(ローテーションは次のステップで設定するため、まずは無効)。
保存した JSON が復号されて返ってくれば成功です(裏で KMS による復号が行われています)。
Secrets Manager の一覧に handson/db-credentials が表示され、CLI で値を取得できれば成功です。値はコンソール上でも「シークレットの値を取得する」を押すまでマスクされています。
handson/db-credentials を開き、「ローテーション」タブ →「ローテーションを編集」をクリックします。
RDS の認証情報タイプなら、AWS 提供のローテーションテンプレート Lambda が自動作成されます。その他のシークレットの場合は雛形 Lambda が作られます。
「ローテーションを今すぐ実行」をクリックします。ローテーション Lambda が新しいパスワードを生成し、シークレットの新バージョン(AWSCURRENT)として保存します。
ローテーション Lambda は、新パスワード生成 → DB に反映 → 接続テスト → ラベル切替(AWSPENDING→AWSCURRENT)という 4 段階で安全に更新します。アプリは常に AWSCURRENT を取得するだけでよく、切替を意識する必要がありません。
ローテーション実行後にパスワードが変化し、「バージョン」に新しい AWSCURRENT が記録されていれば成功です。
コードにパスワードを書かず、実行時に Secrets Manager から取得するパターンを実装します。
CloudShell で以下の Python を実行します。
import boto3, json
session = boto3.session.Session()
client = session.client("secretsmanager", region_name="ap-northeast-1")
resp = client.get_secret_value(SecretId="handson/db-credentials")
secret = json.loads(resp["SecretString"])
print("user:", secret["username"])
print("host:", secret["host"])
# このあと secret["password"] で DB 接続する(パスワードはコードに書かない)
EC2 / Lambda / ECS のロールに、特定シークレットだけ読める権限を付けます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:ap-northeast-1:<AccountId>:secret:handson/db-credentials-*"
},
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "<handson-key の ARN>"
}
]
}
Secrets Manager だけでなく、暗号化に使った KMS キーの kms:Decrypt も必要な点に注意します。
boto3 でシークレットを取得でき、ローテーション後も常に最新のパスワードが返ることを確認できれば、ハードコーディングを排除した安全な構成が完成です。
KMS キーは 1 USD/月、シークレットは 0.40 USD/月の課金があります。使い終わったら削除してください。
SecretsManager... 関数を削除handson/db-credentials → 「アクション」→「シークレットを削除」(待機期間 7〜30 日。最短は CLI で --force-delete-without-recovery)handson-kms-xxxx を空にして削除handson-key → 「キーの削除をスケジュール」(最短 7 日の待機期間。即削除は不可)KMS キーは誤削除によるデータ復号不能を防ぐため、最短 7 日の待機期間後に削除されます。それまでは「削除保留中」で課金は停止します。
| 習得したスキル | 実践内容 |
|---|---|
| KMS キー管理 | カスタマーキー作成・キーポリシー・自動ローテーション |
| SSE-KMS 暗号化 | S3 を KMS で暗号化・CloudTrail で Decrypt 監査 |
| シークレット保管 | Secrets Manager で認証情報を暗号化保管 |
| 自動ローテーション | Lambda による定期パスワード更新・4 ステップの仕組み |
| アプリ参照 | boto3 で実行時取得・最小権限 IAM(SecretsManager + KMS) |