DB パスワードや API キーをコードに直書きするのは、だいたい事故の入口です。
Git に残る。ログに出る。開発者のローカルに散らばる。退職者の端末にも残る。最悪なのは、漏れたあとに「どこを変えればいいのか」が分からなくなることです。
AWS で認証情報を扱うなら、まず検討するのが AWS Secrets Manager です。この記事では、Secrets Manager が何を解決するのか、Parameter Store とどう使い分けるのか、RDS の認証情報ローテーションで何に注意すべきかを整理します。
先に結論
AWS Secrets Manager は、秘密情報を安全に保管し、必要に応じてローテーションするためのサービスです。
単に「パスワードを隠す場所」ではありません。認証情報の取得権限、監査、バージョン管理、ローテーションまで含めて考えるための部品です。
| 判断 | 向いているもの |
|---|---|
| 通常の設定値を管理したい | Systems Manager Parameter Store |
| 暗号化した設定値を置きたい | Parameter Store SecureString |
| DB パスワードや API キーを管理したい | Secrets Manager |
| 認証情報を定期的に入れ替えたい | Secrets Manager |
| RDS のパスワードを自動ローテーションしたい | Secrets Manager |
秘密情報は、置き場所だけ決めても不十分です。誰が読めるか、どう監査するか、いつ入れ替えるか、失敗時に戻せるかまで決めて初めて運用になります。
コード直書きはなぜまずいのか
コードにパスワードを書くと、秘密情報がコードの寿命に引きずられます。
```python
DB_PASSWORD = "SuperSecretPassword123!"
```
これは極端な例ですが、実際には次のような形で似た事故が起きます。
- Git の履歴に残る
- CI のログに出る
- Docker image に残る
- .env が共有される
- チャットやチケットに貼られる
- 退職者や外部委託先の環境に残る
漏れたあとに問題になるのは、「誰が持っているか分からない」ことです。だから、秘密情報は最初から集中管理し、権限とローテーションの設計を持たせる必要があります。
Secrets Manager の役割
Secrets Manager では、シークレットを暗号化して保存し、アプリケーションが実行時に取得できます。
主な要素は次です。
- KMS による暗号化
- IAM による取得権限制御
- CloudTrail による API 呼び出し監査
- シークレットのバージョン管理
- Lambda と連携したローテーション
- RDS などとの連携
構成としては、アプリケーションに直接パスワードを持たせるのではなく、実行ロールに Secrets Manager の読み取り権限を付けます。
```text
Application runtime
-> IAM Role
-> Secrets Manager
-> credential
-> RDS / external API
```
ここで長期アクセスキーをアプリケーションに配ると、本末転倒です。EC2、ECS、Lambda などでは、それぞれの実行ロールを使うのが基本です。
Parameter Store とどう使い分けるか
Parameter Store と Secrets Manager は、どちらも設定値や秘密値を扱えます。だから混同されます。
違いは、どこまで「秘密情報の運用」を持たせたいかです。
| 観点 | Parameter Store | Secrets Manager |
|---|---|---|
| 得意領域 | 設定値管理 | 秘密情報管理 |
| 階層構造 | 扱いやすい | 主目的ではない |
| 暗号化 | SecureString で可能 | 可能 |
| ローテーション | 自前実装になりやすい | 標準的に組み込みやすい |
| RDS 連携 | 手作りになりがち | 扱いやすい |
| コスト感 | 軽めに使いやすい | シークレット単位で課金 |
設定値なら Parameter Store。漏えいしたら困る認証情報で、ローテーションまで考えるなら Secrets Manager。まずはこの分け方で十分です。
RDS の認証情報ローテーション
Secrets Manager が特に効くのは、RDS の認証情報管理です。
RDS のユーザー名とパスワードを Secrets Manager に保存し、ローテーション Lambda を使って定期的に変更できます。
ただし、自動ローテーションを有効にすれば終わりではありません。
確認すべき点は次です。
- アプリケーションが新しいシークレットを再取得できるか
- コネクションプールが古い認証情報を握り続けないか
- ローテーション Lambda の IAM 権限が広すぎないか
- 失敗時に前バージョンへ戻せるか
- 本番前に検証環境で試しているか
RDS 側のパスワードだけ変わって、アプリケーションが古いパスワードを使い続けると普通に接続失敗します。ローテーションはセキュリティ機能である前に、運用手順です。
IAM 権限を絞る
Secrets Manager を使っても、アプリケーションロールに全シークレットの読み取り権限を渡したら意味がありません。
最低限、対象 secret に絞ります。
```json
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/db/app-*"
}
```
さらに、環境ごとに secret を分けます。開発環境のアプリが本番 DB の secret を読める構成は、かなり危険です。
集中管理は便利ですが、集中しているからこそ権限設計を雑にすると被害も集中します。
アプリケーションでの取得設計
Secrets Manager から毎リクエスト取得する設計は、多くの場合やりすぎです。レイテンシもコストも増えます。
一般的には、次のようにします。
- 起動時に取得する
- 一定時間だけキャッシュする
- 取得失敗時のリトライを入れる
- ローテーション後に再取得できるようにする
- 障害時の挙動をログで追えるようにする
秘密情報は隠せば終わりではありません。アプリケーションがどう読むかまで含めて設計対象です。
まとめ
Secrets Manager は、コードから秘密情報を追い出し、認証情報を運用できる形にするためのサービスです。
- DB パスワードや API キーを安全に保管できる
- IAM、KMS、CloudTrail と組み合わせて管理できる
- RDS などの認証情報ローテーションに使いやすい
- Parameter Store は設定値管理、Secrets Manager は秘密情報管理に寄せると分かりやすい
- ローテーションはアプリケーション側の再取得設計まで含めて考える
コードからパスワードを消すだけなら、まだ入口です。誰が読めるか、どう入れ替えるか、失敗したらどう戻すか。そこまで決めて、ようやく秘密情報管理です。
