シークレット管理
Secrets Management Cheat Sheet
- 原典
- Secrets Management Cheat Sheet(OWASP Cheat Sheet Series)
- 原文
- GitHub 上の Markdown
- 底本
bac04fb5(2026-07-29 時点)- ライセンス
- CC BY-SA 4.0(原典と同一。訳文も同ライセンスで再配布できます)
1 はじめに
シークレットは今日あらゆる場所で使われており、DevOps の広まりによってとくにそうなっている。 API キー、データベースの資格情報、IAM(Identity and Access Management)の権限、SSH の鍵、証明書などである。 多くの組織はそれらをソースコードに平文で埋め込み、設定ファイルや構成管理の道具のあちこちに散らしている。
シークレットへのアクセスを制御し、その漏洩と組織の侵害を防ぐため、シークレットの保存、供給、監査、ローテーション、管理を集約する必要が組織で高まっている。 複数のサービスが同じシークレットを共有していることも多く、それが侵害や漏洩の源の特定を難しくする。
このチートシートは、シークレット管理を適切に実装する助けとなる最良の慣行と指針を示す。
2 シークレット管理の全般
以下の節は、シークレット管理に関する主要な考え方を扱う。
2.1 高い可用性
通信を確実に処理できるだけ堅牢な技術を選ぶことが不可欠である。
- 利用者(SSH の鍵、root アカウントのパスワードなど)。事故対応の場面では、利用者は資格情報が迅速に供給されることを期待する。そうすれば停止したサービスを復旧できる。資格情報を待たなければならないことは、運用チームの応答性に影響しうる。
- アプリケーション(データベースの資格情報や API キーなど)。そのサービスの性能が悪ければ、依存するアプリケーションの可用性を落とすか、起動時間を延ばしうる。
大きな組織では、そうしたサービスが相当な量のリクエストを受けうる。
2.2 集約と標準化
DevOps のチームがアプリケーションのために使うシークレットは、マーケティング担当者や SRE チームが保存するシークレットとは異なる形で使われうる。 シークレットの利用側と生成側の必要が食い違うところに、保守の行き届かないシークレットがしばしば見つかる。 したがって、シークレット管理の仕組みを注意深く標準化し集約しなければならない。 標準化と集約は、複数のシークレット管理の仕組みを使うことを意味する場合もある。 たとえば、クラウドネイティブの開発チームはクラウド事業者が提供する仕組みを選び、プライベートクラウドではサードパーティの仕組みを使い、全員が選定されたパスワードマネージャのアカウントを持つ、というようになる。 これら異なる仕組みとのやりとりをチームが標準化する状態にすれば、事故の際にも保守可能で使える状態が保たれる。
企業がシークレット管理を一つの仕組みへ集約しても、その仕組みの主要なシークレットを二次的なシークレット管理の仕組みで守らなければならないことが多い。 たとえばクラウド事業者の機能でシークレットを保存できるが、そのクラウド事業者の root や管理の資格情報はどこか別の場所に保存する必要がある。
標準化には、シークレットの生存期間の管理、シークレット管理の仕組みの認証、認可、記録、そして生存期間の管理を含めるべきである。 あるシークレットが何に使われ、どこにあるのかが組織にとって直ちに明らかであるべきことに注意する。 使うシークレット管理の仕組みが多くなるほど、必要な文書も増える。
2.3 アクセス制御
シークレット管理のシステムで利用者がシークレットを読める、あるいは更新できる場合、そのシークレットはその利用者と、シークレットに触れるために使ったシステムを通じて漏れうることになる。 したがって技術者がシステム内のすべてのシークレットにアクセスできるべきではなく、最小権限の原則を適用するべきである。 最小権限の原則を実現するため、シークレット管理のシステムは各オブジェクトと構成要素に細かい粒度のアクセス制御を設定できる必要がある。
2.4 シークレット管理の自動化
手作業の保守は漏洩のリスクを高めるだけでなく、保守の最中の人為的な誤りのリスクも持ち込む。 さらに無駄も生じうる。 したがって、実際のシークレットに人が関わることを限定するか取り除くほうがよい。 人の関与を制限する方法は複数ある。
- シークレットのパイプライン。シークレット管理の大部分(生成、ローテーションなど)を行うパイプラインを持つ。
- 動的なシークレットを使う。アプリケーションが起動するとき、そのデータベースの資格情報を要求できる。それが動的に生成されるなら、そのセッション向けの新しい資格情報が与えられる。資格情報の再利用の面を減らすため、可能な場所では動的なシークレットを使うべきである。アプリケーションのデータベースの資格情報が盗まれても、再起動時にそれは失効する。
- 静的なシークレットの自動ローテーション。鍵のローテーションは手作業で行うと難しい処理であり、誤りにつながりうる。したがって鍵のローテーションを自動化するか、少なくともその処理が IT によって十分に支えられている状態にするほうがよい。
暗号鍵のような一部の鍵のローテーションは、データの全体または部分の再暗号化を引き起こしうる。 鍵をローテーションする戦略には次のものがある。
- 段階的なローテーション
- 書き込みの操作に新しい鍵を導入する
- 読み取りの操作には古い鍵を残す
- 迅速なローテーション
- 予定に基づくローテーション
- その他
2.4.1 自動ローテーションのアーキテクチャのパターン
シークレットの自動ローテーションに対応するシステムをどう設計するかを示すため、いくつかのアーキテクチャのパターンを挙げる。
例 1。サイドカーコンテナを用いる Kubernetes
Kubernetes の環境では、シークレット管理の仕組みからシークレットを取得し、主たるアプリケーションのコンテナへ渡す役割のサイドカーコンテナを使うのが一般的なパターンである。 これはアプリケーションを、シークレット管理の仕組みの具体的な事情から切り離す。
アーキテクチャ
- Pod が二つのコンテナ(主たるアプリケーションのコンテナと、サイドカーコンテナ(HashiCorp Vault Agent、CyberArk Conjur Secrets Provider など))を含む。
- サイドカーコンテナがシークレット管理の仕組みに対して認証する(Kubernetes のサービスアカウントを使うなど)。
- シークレットを取得し、共有されたメモリ上のボリュームへ書き込む。
- アプリケーションのコンテナが共有ボリュームからシークレットを読む。
- サイドカーコンテナはシークレットを定期的に更新でき、アプリケーションが常に有効で短命な資格情報を持つ状態にする。
Kubernetes のマニフェストの断片
apiVersion: v1 kind: Pod metadata: name: my-app spec: serviceAccountName: my-app-sa containers: - name: my-app-container image: my-app-image volumeMounts: - name: secrets-volume mountPath: "/mnt/secrets" readOnly: true - name: vault-agent-sidecar image: vault:latest args: ["agent", "-config=/etc/vault/vault-agent-config.hcl"] volumeMounts: - name: secrets-volume mountPath: "/mnt/secrets" volumes: - name: secrets-volume emptyDir: medium: "Memory"
例 2。データベースの資格情報のローテーションを行うサーバーレス関数
クラウドネイティブのシークレット管理の仕組みは、サーバーレス関数(AWS Lambda、Azure Functions など)による自動ローテーションの機能を組み込みで提供することが多い。
アーキテクチャ
- シークレットがクラウドのシークレット管理の仕組み(AWS Secrets Manager など)に保存されている。
- そのシークレット管理の仕組みが、予定に従ってローテーションの Lambda 関数を起動するよう設定されている。
- その Lambda 関数は、データベースのパスワードとシークレット管理の仕組み内のシークレットの値を更新する必要な権限を持つ。
- ローテーションの処理は通常、安全な移行を確かにするため複数の段階(新しいシークレットの作成、新しいシークレットの設定、新しいシークレットの検証、ローテーションの完了)を含む。
AWS Lambda のローテーション関数(概念的な Python のコード)
import boto3 import os def lambda_handler(event, context): secret_name = event['SecretId'] token = event['ClientRequestToken'] step = event['Step'] secrets_manager = boto3.client('secretsmanager') # Get the secret metadata metadata = secrets_manager.describe_secret(SecretId=secret_name) if step == "createSecret": # Create a new version of the secret new_password = generate_new_password() secrets_manager.put_secret_value( SecretId=secret_name, ClientRequestToken=token, SecretString=f'{{"password":"{new_password}"}}', VersionStages=['AWSPENDING'] ) elif step == "setSecret": # Update the database with the new password update_database_password(new_password) elif step == "testSecret": # Test the new secret test_database_connection(new_password) elif step == "finishSecret": # Mark the new version of the secret as current secrets_manager.update_version_stage( SecretId=secret_name, VersionStage="AWSCURRENT", MoveToVersionId=token )
これらの例は、シークレットを安全に管理するだけでなくローテーションの処理も自動化し、資格情報が侵害されるリスクを大幅に下げるアーキテクチャの作り方を示す。
2.5 メモリ内でのシークレットの扱い
シークレットがメモリ内にある時間の幅を最小にし、そのメモリ空間へのアクセスを限定することで、安全性の水準をさらに高められる。
アプリケーションの個々の状況によっては、メモリの安全性を確かにする形でこれを実装するのは難しいことがある。 この実装上の複雑さがありうるため、まず脅威モデルを作り、アプリケーションの配備環境についての暗黙の想定を明らかにし、敵の能力を理解することが推奨される。
メモリ内のシークレットを保護しようとすることは、しばしば過剰とみなされる。 脅威モデルを評価すると、想定する脅威の主体がそうした攻撃を実行する能力を持たないか、防御の費用がメモリ内のシークレットの露出から生じる侵害の影響を大きく上回るからである。 また適切な脅威モデルを作るうえで、攻撃者がシークレットを扱うプロセスのメモリにすでにアクセスできているなら、その時点で安全性の侵害はすでに起きている可能性があることを念頭に置くべきである。 さらに、Rowhammer や Meltdown と Spectre のような攻撃の登場によって、OS だけではこの種の攻撃からプロセスのメモリを守るのに十分でないことを理解しておくことが重要である。 これはアプリケーションがクラウドに配備される場合にとくに重要になる。 これらや類似の攻撃からメモリを守る唯一の確実な方法は、プロセスのメモリを他のすべての信頼できないプロセスから完全に物理的に分離することである。
実装の難しさがあっても、非常に機微な環境では、メモリ内のシークレットの保護が価値ある追加の安全の層になりうる。 たとえば高度な攻撃者がシステムをクラッシュさせてメモリダンプへアクセスできる場面では、そこからシークレットを取り出せるかもしれない。 したがって信頼できない環境や、厳しい安全性が最も重要な状況では、メモリ内のシークレットを注意深く守ることが推奨される。
さらに C や C++ のような低い水準の言語では、メモリ内のシークレットを保護するのは比較的容易である。 したがって攻撃者がメモリへアクセスするリスクが低くても、この慣行を実装する価値があるかもしれない。 一方、ガベージコレクションに依拠するプログラミング言語では、メモリ内のシークレットを守ることは一般にはるかに難しい。
- 構造体とクラス:.NET と Java では、シークレットの保存に String のような不変の構造を使わない。ガベージコレクションを強制することが不可能だからである。代わりにバイト配列や文字配列のような基本の型を使い、メモリを直接上書きできる状態にする。
- メモリのゼロ埋め:シークレットを使い終えたら、それが占めていたメモリをゼロで埋め、アクセスされうる状態でメモリに残らないようにするべきである。
- メモリの暗号化:場合によっては、ハードウェアや OS の機能を使い、シークレットを扱うプロセスのメモリ空間全体を暗号化できることがある。これは追加の安全の層を与えうる。
目的は、シークレットが平文でメモリにある時間の幅を可能なかぎり最小にすることであることを忘れない。
さらに詳しくは OWASP MAS プロジェクトの Testing Memory for Sensitive Data を参照する。
2.6 監査
アプリケーションの性質から、監査はシークレット管理に不可欠な部分である。 監査ログの改ざんや削除の試みに耐えるよう、監査は安全に実装しなければならない。 少なくとも次を監査するべきである。
- 誰が、どのシステムと役割のためにシークレットを要求したか。
- そのシークレットの要求が承認されたか拒否されたか。
- そのシークレットがいつ、誰または何によって使われたか。
- そのシークレットがいつ失効したか。
- 失効したシークレットを再利用しようとする試みがあったか。
- 認証や認可のエラーがあったか。
- そのシークレットがいつ、誰または何によって更新されたか。
- 基盤となるインフラのスタック上の管理操作と、利用者の活動の可能性。
すべての監査が正しいタイムスタンプを持つことが不可欠である。 したがってシークレット管理の仕組みは、その基盤に適切な時刻同期のプロトコルを設定しておくべきである。 その仕組みが動くスタックについて、時計のずれと手作業の時刻調整の可能性を監視するべきである。
2.7 シークレットの生存期間
シークレットは生存期間をたどる。 その段階は次のとおりである。
- 生成
- ローテーション
- 失効
- 有効期限切れ
2.7.1 生成
新しいシークレットは安全に生成し、その用途に対して暗号的に十分堅牢でなければならない。 シークレットには、必要な用途や役割を可能にする最小限の権限を割り当てなければならない。
資格情報は安全に伝えるべきである。 理想的には、利用者アカウントを要求するときにユーザー名とともにパスワードを送らない。 代わりにパスワードは安全な経路(相互に認証された接続など)や、プッシュ通知、SMS、メールのような副次の経路で送るべきである。 各経路の利点と難点については多要素認証を参照する。
アプリケーションは複数の通信経路を持つ利点を得られないこともあるので、資格情報の供給は安全に行わなければならない。
シークレットの生成についてのより技術的な推奨は Open CRE のシークレットの項目を参照する。
2.7.2 ローテーション
シークレットは定期的にローテーションするべきである。 そうすれば盗まれた資格情報が短時間しか使えなくなる。 定期的なローテーションは、資格情報の再利用のような悪い習慣に利用者が戻る傾向も減らす。
シークレットの機能とそれが守るものに応じて、その寿命は数分(完全前方秘匿性を持つ端末間暗号化のチャットなど)から数年(ハードウェアのシークレットなど)まで幅がある。
利用者の資格情報は定期的なローテーションの対象外である。 NIST の推奨によれば、それは侵害の疑いや証拠がある場合にのみローテーションするべきである。
2.7.3 失効
シークレットが不要になった、あるいは侵害された可能性がある場合、アクセスを制限するために安全に失効させなければならない。 (TLS の)証明書では、これは証明書の失効も伴う。
2.7.4 有効期限切れ
可能な場合は、定めた時間の後に失効するようシークレットを作るべきである。 この失効は、シークレットを使うシステムによる能動的な失効でもよく、シークレット管理のシステムに設定した有効期限が支援する処理を起動し、シークレットのローテーションに至る形でもよい。 資格情報の種類に応じた限られた時間だけ使える状態にするため、シークレット管理の仕組みを通じて方針を適用するべきである。 アプリケーションは、そのシークレットを信頼する前にまだ有効であることを検証するべきである。
2.8 あらゆる場所での TLS
シークレットを平文で送ることは決してしない。 TLS が広く普及した今日、その言い訳は成り立たない。
さらに、シークレット管理の仕組みは TLS 証明書の供給にも実効的に使える。
2.9 停止、緊急時の手段、バックアップと復元
保守のための予定された停止など、さまざまな理由でシークレット管理のサービスが使えなくなる可能性を考える。 サービスの復旧に必要な資格情報を事前に入手していなければ、それを取得できなくなりうる。 したがって、以前の計測値と監査ログに基づいて保守の時間帯を注意深く選ぶ。
次に、そのシステムのバックアップと復元の手順は、その安全性について定期的に試験し監査するべきである。 バックアップと復元についての要件をいくつか挙げる。
- 自動のバックアップの手順が整い、定期的に実行されている状態にする。バックアップとスナップショットの頻度は、シークレットの数とその生存期間に基づいて決める。
- バックアップが無事であることを保証するため、復元の手順を頻繁に試験する。
- バックアップを暗号化し、アクセス権を絞った安全な保存領域に置く。バックアップの場所について(認可されていない)アクセスと管理操作を監視する。
最後に、通常の保守以外の理由でシステムが使えなくなった場合にサービスを復旧する緊急時(ブレークグラス)の手続きを実装するべきである。 したがって緊急時のブレークグラスの資格情報は、二次的なシークレット管理のシステムへ定期的に安全にバックアップし、動作を検証するために日常的に試験するべきである。
2.10 方針
パスワードの最小の複雑さの要件と承認された暗号アルゴリズムを定める方針を、組織全体の水準で一貫して強制する。 集約されたシークレット管理の仕組みを使えば、企業がこれらの方針を実装する助けになる。
次に、組織全体のシークレット管理の方針を持てば、このチートシートで定めた最良の慣行の適用を強制する助けになる。
2.11 メタデータ。シークレットの移行に備える
シークレット管理の仕組みは、シークレットについて少なくとも次のメタデータを保存できる機能を提供するべきである。
- いつ生成、使用、保管、ローテーション、削除されたか
- 誰が生成、使用、保管、ローテーション、削除したか(実際の生成者と、その方法を用いた技術者の両方など)
- 何が生成、使用、保管、ローテーション、削除したか
- そのシークレットで問題が起きたとき、あるいはそれについて質問があるときの連絡先
- そのシークレットが何に使われるのか(意図された利用側とシークレットの目的など)
- どの種類のシークレットか(AES の鍵、HMAC の鍵、RSA の秘密鍵など)
- 手作業で行う場合、いつローテーションする必要があるか
注記:シークレットについてのメタデータを保存せず、移行に備えなければ、特定のベンダーに固定される可能性が高まる。
2.12 パスワードのない認証とトークンの安全性
すべての種類のシークレット(API キー、データベースの資格情報など)を直接置き換えるものではないが、**OpenID Connect(OIDC)**のようなパスワードのない認証の仕組みは、利用者が管理するパスワードから離れることで攻撃対象領域を大きく減らせる。 パスワードの代わりに、アプリケーションは信頼されたアイデンティティプロバイダ(IdP)に利用者の認証を任せ、安全なトークンを受け取る。
どう役立つか
- パスワードに関するリスクを減らす:フィッシング、クレデンシャルスタッフィング、弱いパスワードの慣行といった脅威をなくす。
- アイデンティティ管理の集約:認証を専門の IdP が扱い、強固な認証の方針(MFA など)を強制できる。
- 短命なセッション:OIDC のトークンは通常短命であり、トークンが侵害された場合に攻撃者が使える時間の幅を限定する。
トークンの安全性が決定的に重要である
パスワードのない認証を採ることは、安全性の焦点を静的なパスワードの保護から、動的なトークン(ID トークン、アクセストークン、リフレッシュトークンなど)の保護へ移す。 これらのトークンは bearer トークンであり、それを持つ者は誰でも使える。 したがって次が決定的に重要である。
- トークンの安全な送信:トークンは常に TLS 上で送る。
- 保存されたトークンの保護:ブラウザのローカルストレージのような安全でない場所にトークンを保存しない。安全な HTTP-only の Cookie か、モバイルアプリケーションに適した安全な保存の仕組みを使う。
- トークンの正しい検証:トークンが正当であることを確かにするため、常に署名、発行者、対象者を検証する。
- トークンの寿命の管理:短命なアクセストークンを使い、安全なリフレッシュトークンのローテーションの戦略を実装する。
OAuth 2.0 と OpenID Connect の実装を安全にする詳しい指針は OAuth 2.0 プロトコルを参照する。
3 継続的インテグレーション(CI)と継続的デプロイ(CD)
変更の構築、試験、配備は一般に多くのシステムへのアクセスを要する。 CI と CD の道具は通常、アプリケーションへの設定を与えるため、あるいは配備の最中に使うためにシークレットを保存する。 あるいはシークレット管理のシステムと密にやりとりする。 CI/CD におけるシークレット管理を円滑にする最良の慣行はさまざまあり、この節ではそのいくつかを扱う。
3.1 CI/CD のパイプラインを堅牢にする
CI/CD の道具は(高い権限を持つ)資格情報を日常的に使う。 そのパイプラインが容易に侵害されたり従業員に濫用されたりしない状態にする。 役立つ指針をいくつか挙げる。
- CI/CD の道具を本番環境として扱う。堅牢にし、パッチを当て、基盤のインフラとサービスも堅牢にする。
- セキュリティ事象の監視を整える。
- 最小権限のアクセスを実装する。開発者はプロジェクトを管理できる必要はない。パイプラインの設定、その実行、コードの作業といった必要な機能を実行できればよい。管理の作業は、CI/CD のシステムが自身の設定を更新するために使う別のリポジトリで、コードとしての設定によって手早く行える。シークレットへアクセスできる特権的な役割は不要である。
- パイプラインの出力がシークレットを漏らさない状態にし、デバッグの道具で本番のパイプラインを盗み見られない状態にする。
- CI/CD のシステムのランナーやワーカーに入り込めない状態にする。
- 適切な認証、認可、記録を整える。
- 承認された処理のみがパイプラインを作れる状態にする。作られたパイプラインが安全性の観点で精査される状態にするため、マージリクエストやプルリクエストの段階を含める。
3.2 シークレットはどこにあるべきか
CI/CD の動作を実行するためにシークレットを保存できる場所はいくつかある。
- CI/CD の道具の一部として。GitLab、GitHub、Jenkins にシークレットを保存できる。これはコードにコミットすることとは異なる。
- シークレット管理のシステムの一部として。クラウド事業者が提供する機能(AWS Secrets Manager、Azure Key Vault、Google Secret Manager)や、その他のサードパーティの機能(HashiCorp Vault、Conjur、Keeper)のようなシークレット管理のシステムに保存できる。この場合、CI/CD のパイプラインの道具がこれらのシークレット管理のシステムへ接続する資格情報を必要とする。クラウド事業者のシークレット管理の仕組みの利用についてさらに詳しくはクラウド事業者を参照する。
もう一つの選択肢は、CI/CD のパイプラインからシークレット管理のシステムの Encryption as a Service を活用してシークレットを暗号化することである。 CI/CD の道具は暗号化されたシークレットを git にコミットでき、それを配備時に利用側のサービスが取得して復号できる。 さらに詳しくは 3.6 節を参照する。
注記:実際の配備に至るまでに、すべてのシークレットが CI/CD のパイプラインにある必要はない。 むしろ配備されたサービスが、自身の生存期間(配備、実行、破棄)においてシークレット管理の一部を担う状態にする。
3.2.1 CI/CD の道具の一部として
シークレットが CI/CD の道具の一部である場合、それらのシークレットは CI/CD のジョブに露出することを意味する。 CI/CD の道具には GitHub のシークレット、GitLab のリポジトリのシークレット、Microsoft Azure DevOps の環境変数や変数グループ、Kubernetes の Secret などが含まれうる。 これらのシークレットは、権限を持つ人(GitHub のメンテナ、GitLab のプロジェクトの所有者、Jenkins の管理者など)によってしばしば設定や閲覧が可能であり、次の最良の慣行につながる。
- 「大きなシークレット」を置かない。CI/CD の道具に置くシークレットが、長期のものでなく、影響範囲が広くなく、価値が高くない状態にする。また共有されるシークレットを限定する(管理者全員に一つのパスワードを持たせるようなことを決してしない)。
- 現状と目標。どの利用者がシークレットを閲覧または変更できるかを明確に把握する。GitLab や GitHub のプロジェクトのメンテナは、しばしばそのシークレットを見るか、他の方法で取り出せる。
- 露出を限定するため、そのプロジェクトで管理の作業を行える人の数を減らす。
- 記録と警報。CI/CD の道具からログをすべて集め、シークレットの取り出しや濫用を検知する規則を整える。Web のインタフェースからのアクセスによるものも、Base64 で二重にエンコードしたり OpenSSL で暗号化したりして持ち出すものも対象にする。
- ローテーション。シークレットを定期的にローテーションする。
- フォークで漏らさない。リポジトリのフォークやジョブの定義の複製がシークレットを複製しないことを検証する。
- 文書化。CI/CD の道具の一部としてどのシークレットをなぜ保存しているのかを文書化し、必要になったときに容易に移行できる状態にする。
3.2.2 シークレット管理のシステムに保存する
当然、専用のシークレット管理の仕組みにシークレットを保存できる。 たとえば(クラウドの)インフラ事業者が提供する仕組み(AWS Secrets Manager、Google Secret Manager、Azure Key Vault)を使える。 これらについてさらに詳しくはこのチートシートの 4 節にある。 もう一つの選択肢は、HashiCorp Vault、Keeper、Conjur のような専用のシークレット管理のシステムである。
これらのシステムとの CI/CD のやりとりについて、すべきこととすべきでないことを挙げる。 次が守られている状態にする。
- ローテーションと一時性。CI/CD の道具がシークレット管理のシステムに対して認証するために使う資格情報を頻繁にローテーションし、ジョブの完了後に失効させる。
- 認可の範囲。CI/CD の道具が使う資格情報(役割、利用者など)の範囲を絞り、CI/CD の道具がジョブを実行するために必要なシークレット管理のシステムのシークレットとサービスのみを認可する。
- 呼び出し元の帰属。CI/CD の道具が使う資格情報も、シークレット管理の仕組みを呼び出した者への帰属を保つ。CI/CD の道具が行ったすべての呼び出しを、その動作を要求した人やサービスに帰属させられる状態にする。シークレット管理の仕組みの既定の設定でこれが不可能なら、リクエストのパラメータの面で対応づけの仕組みを整える。
- 上記のすべて。3.2.1 節に挙げたすべきこととすべきでないことも守る。記録と警報、フォークへの対処などである。
- バックアップ。製品にとって重要な運用のシークレット、とくに暗号鍵は、別の保存領域(コールドストレージなど)にバックアップする。
3.2.3 CI/CD がまったく触れない
シークレットは必ずしも CI/CD のパイプラインによって利用側へ届けられる必要はない。 シークレットの利用側がそれを取得するほうがむしろよい。 その場合でも CI/CD のパイプラインは、利用側が必要なシークレットを取得できるよう、所定のサービスアカウントを伴う特定のサービスの配置を、統制のシステム(Kubernetes など)へ指示する必要がある。 CI/CD の道具はそのとき統制のプラットフォーム向けの資格情報をなお持つが、シークレット自体へのアクセスはもう持たない。 この種の資格情報についてのすべきこととすべきでないことは、3.2.2 節で述べたものと似ている。
3.3 CI/CD の道具の認証と認可
CI/CD の道具は所定のサービスアカウントを持つべきであり、それは必要なシークレット、あるいはシークレットの利用側の統制の範囲でのみ動作できるものであるべきである。 加えて、CI/CD のパイプラインの実行は、ジョブを定義した者やそれを起動した者に容易に帰属できるべきである。 誰がシークレットの持ち出しや操作を試みたのかを検出するためである。 証明書に基づく認証を使う場合、パイプラインの呼び出し元の身元が証明書の一部であるべきである。 上述のシステムに対する認証にトークンを使う場合は、これらの動作を要求した主体(利用者やジョブの作成者)を設定する状態にする。
自分のシステムでこれが(なお)成り立っているかを定期的に検証し、記録、帰属、疑わしい動作に対する安全上の警報を実効的に行える状態にする。
3.4 記録と説明責任
攻撃者は CI/CD の道具を使ってシークレットを取り出しうる。 たとえば管理のインタフェースを使う、あるいは暗号化や Base64 の二重エンコードでシークレットを持ち出すジョブを作る。 したがって CI/CD の道具におけるすべての動作を記録するべきである。 シークレットの使用を監視するため、パイプラインの道具とその管理のインタフェースに対する標準外の操作すべてについて、安全上の警報の規則を定義するべきである。 ログは少なくとも 90 日間検索でき、より長い期間はコールドストレージに保存されるべきである。 攻撃者が CI/CD の道具を使ってどのようにシークレットを持ち出したり操作したりできるのかを理解するには、セキュリティチームに時間がかかることがある。
3.5 ローテーションと動的な生成
CI/CD の道具を活用してシークレットをローテーションする、あるいは他の構成要素にローテーションを指示できる。 たとえば CI/CD の道具が、シークレット管理のシステムや別のアプリケーションにシークレットのローテーションを要求できる。 あるいは CI/CD の道具や他の構成要素が動的なシークレットを用意できる。 これは利用側が生きているあいだだけ使うシークレットである。 利用側が消えればそのシークレットは無効になる。 この手順はシークレットの漏洩の可能性を減らし、濫用の検知を容易にする。 攻撃者が利用側の IP 以外からシークレットを使えば、容易に検知できる。
3.6 パイプラインが生成するシークレット
パイプラインの道具を使ってシークレットを生成し、その道具が配備するサービスへ直接与えるか、シークレット管理の仕組みへ渡せる。 あるいはシークレットを暗号化して git に保存し、シークレットとそのメタデータが開発者の日々の作業場所にできるだけ近い状態にもできる。 git に保存するシークレットでは、開発者自身がそれを復号できず、シークレットの各利用側がそれぞれの暗号化された変種を持つ必要がある。 たとえばシークレットは開発、試験、受入、本番の各環境で異なり、別の鍵で暗号化されるべきである。 各環境において、その環境の所定の利用側のみがその固有のシークレットを復号できるべきである。 シークレットは環境をまたいで漏れず、それでもコードのそばに容易に保存できる。
シークレットの利用側は、5.2 節で述べるようにサイドカーを使ってシークレットを復号できる。 シークレットを取得するのではなく、利用側はサイドカーを活用してシークレットを復号する。
パイプラインが自らシークレットを作る場合は、関わるスクリプトやバイナリがシークレット生成の最良の慣行に従う状態にする。 最良の慣行には、安全なランダム性、生成するシークレットの適切な長さなどが含まれ、そのシークレットが git やどこかに保存されたよく定義されたメタデータに基づいて作られることも含まれる。
4 クラウド事業者
クラウド事業者については、少なくとも四つの重要な話題がある。
- 専用のシークレットの保存と管理の仕組み。どのサービスを使うのか。
- エンベロープ暗号化とクライアント側の暗号化
- IAM。影響範囲を狭める
- API の割り当てやサービスの上限
4.1 使うサービス
どの環境でも、専用のシークレット管理の仕組みを使うのが最善である。 ほとんどのクラウド事業者は、シークレット管理を提供するサービスを少なくとも一つ持つ。 もちろん、クラウド内の計算資源で別のシークレット管理の仕組み(HashiCorp Vault や Conjur など)を動かすこともできる。 この節ではクラウド事業者のサービスを扱う。
クラウド事業者が提供するサービスや(自作の)関数によって、シークレットを自動的にローテーションできる場合もある。 一般に、クラウド事業者の仕組みを優先するべきである。 導入の障壁と設定を誤るリスクが低いからである。 自作の仕組みを使う場合は、ローテーションを行う関数の役割をその関数だけが引き受けられる状態にする。
4.1.1 AWS
AWS では、推奨される仕組みは AWS Secrets Manager である。
権限はシークレットの水準で与えられる。 Secrets Manager の最良の慣行を参照する。
より安価な Systems Manager Parameter Store も使えるが、いくつか難点がある。
- 暗号化を自分で指定する必要がある(Secrets Manager は既定で行う)
- 自動ローテーションの機能が少ない(自作の関数を作る必要が生じる可能性が高い)
- アカウントをまたぐアクセスに対応しない
- リージョンをまたぐ複製に対応しない
- 使える Security Hub の統制が少ない
4.1.1.1 AWS Nitro Enclaves
AWS Nitro Enclaves を使えば、シークレットのような非常に機微なデータをさらに保護し安全に処理する、隔離された計算環境を作れる。 Enclave は堅牢化されており運用者のアクセスを制限し、信頼された実行環境を提供する。 主要な機能は暗号によるアテステーションであり、Enclave の身元を検証し、シークレットを供給する前に認可されたコードのみが動いていることを確かにできる。 これはシークレットの扱いに高い確度を要する場面での強い選択肢になる。
4.1.1.2 AWS CloudHSM
非常に機密性の高いアプリケーションで使うシークレットでは、これらの鍵の暗号化と保存をより制御する必要が生じうる。 AWS は CloudHSM を提供しており、AWS のサービスに自前の鍵(BYOK)を持ち込める。 これにより鍵の生成、生存期間、耐久性をより制御できる。 CloudHSM はデータの自動的な拡張とバックアップを可能にする。 クラウド事業者である Amazon は、AWS CloudHSM に保存された鍵の素材へアクセスできない。
4.1.2 GCP
GCP では、推奨されるサービスは Secret Manager である。
権限はシークレットの水準で与えられる。
Secret Manager の最良の慣行を参照する。
4.1.2.1 Google Cloud Confidential Computing
GCP Confidential Computing は、処理中のデータを暗号化する技術である。 これは AMD Secure Encrypted Virtualization(SEV)を活用する Confidential VM や Confidential GKE Node のようなサービスによって実現される。 これにより Google の担当者でも仮想マシンのメモリの内容を見られなくなり、メモリに保持しなければならないシークレットに高い水準の保護を与える。
4.1.3 Azure
Azure では、推奨されるサービスは Key Vault である。
他のクラウドと異なり、権限は Key Vault の水準で与えられる。 つまり、別々のワークロードや別々の機微さの水準のシークレットは、それに応じて別々の Key Vault に置くべきである。
Key Vault の最良の慣行を参照する。
4.1.3.1 Azure Confidential Computing
Azure Confidential Computing を使えば、信頼された実行環境を作れる。 この技術は機微なデータを保護されたコンテナ内に隔離し、保存時、転送時、使用時のいずれでも暗号化されている状態にする。 Azure Confidential Virtual Machines や ACI 上の Confidential Containers のようなサービスは、Intel SGX や AMD SEV-SNP のような技術を用いてこの安全な Enclave を作る。 これはクラウドの管理者、マルウェア、他のテナントからの不正なアクセスを防ぎ、シークレット管理の堅牢な解決策になる。
4.1.3.2 Azure Dedicated HSM
Azure の環境で使われ、特別な安全上の考慮を要するシークレットのために、Azure は Azure Dedicated HSM を提供している。 これにより、そこに保存されたシークレットをより制御でき、管理面と暗号面の統制も強まる。 クラウド事業者である Microsoft は、Azure Dedicated HSM に保存された鍵の素材へアクセスできない。
4.1.4 その他のクラウド、マルチクラウド、クラウド非依存
複数のクラウド事業者を使っている場合は、クラウドに依存しないシークレット管理の仕組みを検討するべきである。 これによりすべてのクラウド事業者(場合によってはオンプレミスでも)で同じシークレット管理の仕組みを使える。 もう一つの利点は、その仕組みがどのクラウド事業者でも使えるため、特定のクラウド事業者への固定を避けられることである。
オープンソースと商用の仕組みがある。 例を挙げる。
4.2 エンベロープ暗号化とクライアント側の暗号化
この節は、シークレットがどう暗号化されるのか、そしてクラウドでその暗号化の鍵をどう管理できるのかを述べる。
4.2.1 クライアント側の暗号化とサーバー側の暗号化
シークレットのサーバー側の暗号化は、保存されたシークレットの暗号化をクラウド事業者が担うことを意味する。 そのシークレットは保存時の侵害から守られる。 保存時の暗号化は、暗号化に使う鍵を選ぶこと(4.2.2 節を参照)以外に追加の作業を要さないことが多い。 ただしそのシークレットを別のサービスへ渡すとき、それはもう暗号化されていない。 意図されたサービスや人へ共有される前に復号される。
シークレットのクライアント側の暗号化は、能動的に復号するまでシークレットが暗号化されたままである状態を確かにする。 つまり利用側に届いたときにのみ復号される。 これに応えるには適切な暗号のシステムを持つ必要がある。 安全な設定で PGP を使う仕組みや、より拡張しやすく比較的使いやすい他の仕組みを考える。 クライアント側の暗号化は、生成側から利用側までシークレットの端末間の暗号化を与えうる。
4.2.2 自前の鍵とクラウド事業者の鍵
シークレットを保存時に暗号化するとき、どの鍵を使いたいかという問いが生じる。 クラウド事業者への信頼が低いほど、自分で管理したくなる。
多くの場合、シークレット管理のサービスで管理される鍵でシークレットを暗号化するか、クラウド事業者の鍵管理の仕組みを使って暗号化するかを選べる。 クラウド事業者の鍵管理の仕組みで提供される鍵は、クラウド事業者が管理することも、自分で管理することもできる。 業界の標準では後者を「自前の鍵を持ち込む」(BYOK)と呼ぶ。 この鍵は鍵管理の仕組みで直接取り込むか生成するか、クラウド事業者が対応するクラウド HSM を使って用意できる。 そのうえで、自分の鍵か事業者のカスタマーメイン鍵を使って、シークレット管理の仕組みのデータ鍵を暗号化できる。 そのデータ鍵が、さらにシークレットを暗号化する。 CMK を管理することで、シークレット管理の仕組みにおけるデータ鍵を制御できる。
自前の鍵の素材の取り込みは一般にどの事業者でも行えるが(AWS、Azure、GCP)、何をしているかを理解していて、脅威モデルと方針がそれを要求する場合を除き、複雑さと使いにくさのために推奨される方法ではない。
4.3 IAM
IAM はオンプレミスにもクラウドの構成にもあてはまる。 シークレットを実効的に管理するには、適切なアクセスの方針と役割を整える必要がある。 これはシークレットに関する方針を超え、IAM の構成全体の堅牢化を含めるべきである。 そうでなければ権限昇格の攻撃を許しうる。 開いた「pass role」の権限や制限のない IAM 作成の権限を決して許さない状態にする。 これらはシークレットへアクセスできる資格情報を使ったり作ったりできる。 次に、何がサービスアカウントを装えるのかを厳密に制御する状態にする。 サーバーを悪用する攻撃者から、機器の役割へアクセスできてしまうか。 データパイプラインの道具のサービスの役割が、シークレットへ容易にアクセスできてしまうか。 クラウドのすべての構成要素について IAM を脅威モデルに含める状態にする(この構成要素で権限昇格をどう起こせるかを自問する)。 例を伴う複数のすべきこととすべきでないことはこの記事を参照する。
IAM の主体の一時性を実効的に活用する。 たとえば、必要とする特定の役割とサービスアカウントのみがシークレットへアクセスできる状態にする。 これらのアカウントを監視し、誰または何がそれを使ってシークレットへアクセスしたのかがわかる状態にする。
次に、シークレットへのアクセスの範囲を絞る状態にする。 すべてのシークレットへ単純にアクセスできてはならない。 GCP と AWS では、主体がすべてのシークレットへ一度にアクセスできないよう、細かい粒度のアクセスの方針を作れる。 Azure では、Key Vault へのアクセスを持つことがその Key Vault 内のすべてのシークレットへのアクセスを意味する。 したがって Azure で作業するときは、アクセスを分離するために別々の Key Vault を持つことが不可欠である。
4.4 API の上限
クラウドのサービスは一般に、一定の期間に行える API の呼び出しの量に上限を設ける。 その上限に達すると、自らサービス妨害を招きうる。 これらの上限のほとんどはアカウント、プロジェクト、サブスクリプションごとに適用されるので、影響範囲を限定するためにワークロードを分散する。 加えて、サービスによってはデータ鍵のキャッシュに対応し、鍵管理のサービスの API への負荷を防げる(AWS のデータ鍵のキャッシュなどを参照)。 組み込みのデータ鍵のキャッシュを活用できるサービスもある。 S3 はその一例である。
5 コンテナと統制の仕組み
コンテナにシークレットを与える方法は複数ある。 構築時(推奨されない)と、統制や配備の最中である。
5.1 シークレットの注入(ファイル、メモリ内)
Docker のコンテナ内のアプリへシークレットを届ける方法は三つある。
- マウントされたボリューム(ファイル)。この方法では、シークレットを特定の設定やシークレットのファイル内に置き、そのファイルをマウントされたボリュームとしてインスタンスへマウントする。これらのマウントは統制の仕組みによって行われ、決して組み込みにしない状態にする。組み込みにすると、コンテナの定義とともにシークレットが漏れる。必要なときに統制の仕組みがそのボリュームをマウントする状態にする。
- シークレットの保管庫から取得する(メモリ内)。サイドカーのアプリやコンテナが、Docker の設定を扱わずにシークレット管理のサービスから直接必要なシークレットを取得する。この方法により、ファイルシステムから見えたり Docker コンテナの環境変数を確認されたりする心配なく、動的に構成されたシークレットを使える。
- 環境変数。Docker コンテナの設定の一部としてシークレットを直接与えられる。注記:シークレット自体を docker の ENV や ARG のコマンドで決して埋め込まない。それはコンテナの定義とともに容易に漏れる。WrongSecrets の Docker の課題も参照する。代わりに統制の仕組みが実際のシークレットで環境変数を上書きする形にし、埋め込まれない状態にする。加えて環境変数は一般にすべてのプロセスからアクセスでき、ログやシステムのダンプに含まれうる。したがって他の方法が不可能な場合を除き、環境変数の使用は推奨されない。
5.2 短命なサイドカーコンテナ
シークレットを注入するために、リモートのエンドポイントからシークレットを取得し、元のコンテナにマウントされた共有ボリュームへ保存する短命なサイドカーコンテナを作れる。 元のコンテナは、マウントされたボリュームからそのシークレットを使える。 この方法の利点は、シークレットを得るためにサードパーティの道具やコードを組み込む必要がないことである。 サイドカーがシークレットを取得したら、それは終了する。 例には Vault Agent Sidecar Injector と Conjur Secrets Provider がある。 Pod と共有されるボリュームにシークレットをマウントすることで、Pod 内のコンテナはシークレット管理の仕組みを意識せずにシークレットを使える。
5.3 内部からのアクセスと外部からのアクセス
シークレットは、コンテナと配備の表現(Kubernetes の Pod など)のあいだの通信の仕組みにのみ露出させるべきである。 配備や統制の仕組みのあいだで共有される外部からのアクセスの仕組み(共有ボリュームなど)を通じて、シークレットを決して露出させない。
統制の仕組みがシークレットを保存する場合(Kubernetes の Secret など)、その保存のバックエンドが暗号化されており、鍵を適切に管理している状態にする。 さらに詳しくは Kubernetes のセキュリティを参照する。
6 実装の指針
この節では実装を論じる。 実際の実装については、選んだシークレット管理のシステムの公式文書を参照するのが常に最善であることに注意する。 このチートシートのような二次的な文書より最新であるからである。
6.1 鍵の素材の管理の方針
鍵の素材の管理は鍵管理で論じている。
6.2 動的な用途と静的な用途
動的なシークレットの用途として、次のようなものがある。
- 主たるサービス(利用側)をあるサービスへ接続する意図を表す、二次的なサービス向けの短命なシークレット(資格情報や API キーなど)。
- メモリ内と実行時の通信の処理を守り安全にするための、短命な完全性と暗号化の対策。単一のセッションや単一の配備の期間だけ存在すればよい暗号鍵を考える。
- サービスの配備の最中にスタックを構築し、配備の担い手や基盤とやりとりするための短命な資格情報。
これらの動的なシークレットは、接続先のサービスとともに作る必要があることが多いことに注意する。 この種の動的なシークレットを作るには、通常それ自体を作るための長期の静的なシークレットが必要になる。 その他の静的な用途を挙げる。
- 同じサービスの他のインスタンスとのやりとりにおける使われ方の性質から、単一の配備より長く存在する必要のある鍵の素材(保存の暗号鍵、TLS の PKI の鍵など)。
- 一時的な役割や資格情報の作成に対応しないサービスへ接続するための鍵の素材や資格情報。
6.3 制限を整える
シークレットは、誰でも何でも取得できるものであっては決してならない。 常に歯止めを整える状態にする。
- アクセスの方針を作れるか。シークレットを読み書きできる実体の数を限定する方針が整っている状態にする。同時に、容易に拡張でき、理解が難しすぎない形で方針を書く。
- シークレット管理の仕組み内で特定のシークレットへのアクセスを絞る方法がないか。本番と開発のシークレットを別々のシークレット管理の仕組みで分けることを検討する。そのうえで本番のシークレット管理の仕組みへのアクセスを絞る。
6.4 セキュリティ事象の監視が鍵になる
誰または何が、どの IP から、どの方法でシークレットへアクセスするのかを継続的に監視する。 注意すべきパターンはさまざまあり、次のものに限られない。
- シークレット管理のシステムで誰がシークレットへアクセスするのかを監視する。それは通常の振る舞いか。CI/CD の資格情報が、CI/CD のシステムが動いている場所とは異なる IP からシークレット管理の仕組みへアクセスするのに使われていれば、安全上の警報を出し、そのシークレットが侵害されたと想定する。
- 可能であれば、シークレットを必要とするサービスを監視する。たとえばシークレットの利用者が想定される IP から、想定されるユーザーエージェントで来ているか。そうでなければ警報を出し、そのシークレットが侵害されたと想定する。
6.5 使いやすさと導入の容易さ
シークレット管理の仕組みが実効的であるには、開発者が採り入れて使うのが容易でなければならない。 処理が複雑すぎれば、開発者は安全でない慣行に走りうる。 使いやすさと円滑な導入の体験への注意は決定的に重要である。
- 明確で網羅的な文書
- 明確で簡潔で見つけやすい文書を提供する。一般的な用途のための手引き、詳細な API の参照、実用的な例を含める。
- 新しい利用者が最初のシークレットを得るまでの流れを案内する「はじめに」の手引きを維持する。
- 開発者に親切な道具と SDK
- 統合を単純にするため、各種のプログラミング言語向けによく保守された SDK を提供する。
- 開発者がローカルの開発環境からシークレットを管理できるコマンドラインインタフェース(CLI)を提供する。
- 一般的な IDE、CI/CD のシステム、Terraform や Pulumi のような Infrastructure as Code の道具向けのプラグインを開発する。
- 流れの合理化
- 開発者が手作業の介入を最小限にしてシークレットを要求し受け取れる、セルフサービスの流れを実装する。
- GitOps の原則を用いてシークレットをコードとして管理し、開発者がアプリケーションのコードのそばで宣言的にシークレットの必要を定義できるようにする。
- リスクの低いシークレットについては承認の処理を自動化し、より機微なものには適切な統制を保つ。
- 実行可能な手がかりと支援
- 開発者が自力で問題を切り分けられる明確なエラーメッセージを提供する。
- 開発者がセキュリティやプラットフォームのチームから助けを得られる専用の支援の経路(Slack のチャンネル、チケットのシステムなど)を設ける。
- 容易な統合
- シークレット管理の仕組みが既存のアプリケーションと容易に統合できる状態にする。Vault Agent Sidecar Injector や Conjur Secrets Provider のようなサイドカーコンテナは、アプリケーションをシークレット管理のシステムから切り離す助けになる。
7 暗号化
シークレット管理は暗号化と密接に結びつく。 結局のところ、シークレットは機密性と完全性を守るためにどこかに暗号化して保存しなければならない。
7.1 使う暗号の種類
十分な安全性、量子計算機に基づく攻撃への適切な耐性を含めて備えているかぎり、シークレットを守るのに各種の暗号を使える。 これは動きのある分野なので、既存の標準における暗号の種類と鍵長についての最新の推奨を列挙する keylength.com のような情報源、そして耐量子のアルゴリズムを列挙する NSA の Commercial National Security Algorithm Suite 2.0 を参照するのが最善である。
いずれの場合も、暗号化と機密性を同時に与えるアルゴリズムを優先して選ぶ必要があることに注意する。 GCM(Galois Counter Mode)を用いた AES-256 や、この分野の最良の慣行に従った ChaCha20 と Poly1305 の組み合わせなどである。
7.2 収束暗号化
収束暗号化は、ある平文とその鍵が同じ暗号文になることを保証する。 これは同じ暗号文になることによって、シークレットの再利用の可能性を検出する助けになる。
収束暗号化を有効にする際の難点は、それによって攻撃者がそのシステムを使い、同じシークレットに至りうる暗号文の集合を生成でき、平文のシークレットを導き出せるようになることである。 アルゴリズムと鍵が与えられたとき、使う収束暗号のシステムが暗号化の際に十分な資源上の困難を伴うなら、このリスクは緩和できる。 リスクを減らす助けになるもう一つの要素は、シークレットが十分な長さを持つ状態にすることであり、これは必要な推測の反復時間をさらに妨げる。
7.3 暗号鍵はどこに保存するか
鍵自体が暗号化されている場合(エンベロープ暗号化を参照)を除き、暗号鍵をそれが暗号化するシークレットのそばに保存すべきではない。 暗号鍵と HMAC の鍵をどこにどう保存するかは、まず鍵管理を参照する。
7.4 Encryption as a Service(EaaS)
EaaS は、自分のシステムに暗号化を導入せずに、クラウドに基づく暗号化のサービスを購読するモデルである。 EaaS を使えば次の利点が得られる。
- 保存時の暗号化
- 転送時の暗号化(TLS)
- 鍵の扱いと暗号の実装が、開発者ではなく暗号化のサービスによって担われる
- 機微なデータを扱うサービスを事業者が追加できる
8 検出
シークレットの検出には多くの方法があり、これを助ける非常に有用なオープンソースのプロジェクトもいくつかある。 Yelp Detect Secrets のプロジェクトは成熟しており、約 20 種類のシークレットに対する特徴の照合を備える。 検出の領域で役立つ他の道具についてさらに詳しくは、GitHub の Secrets Detection のトピックを参照する。
8.1 検出の一般的な方法
シフトレフトと DevSecOps の原則はシークレットの検出にもあてはまる。 以下の一般的な方法は、シークレットをより早い段階で考慮し、その慣行を時間とともに育てることを狙う。
- 標準の試験用シークレットを作り、組織全体で普遍的に使う。これにより、シークレットの種類ごとに一つの試験用シークレットを追跡するだけで済み、誤検知を減らせる。
- IDE 内で、テスト駆動開発の一部として、あるいはコミット前のフックで、コミットやプルリクエストの前にシークレットがコードへ入ることを避けるため、開発者の水準でシークレットの検出を有効にすることを検討する。
- シークレットの検出を脅威モデルの一部にする。脅威モデリングの作業において、シークレットを攻撃対象領域の一部として考える。
- 検出の道具と関連する特徴を頻繁に評価し、期待に応えている状態にする。
- 複数の検出の道具を持ち、結果を対応づけて重複を除くことで、検出の弱点になりうる箇所を特定することを検討する。
- エントロピーと検出の容易さのあいだの釣り合いを探る。形式が一定のシークレットは誤検知率を低く抑えて検出しやすいが、人が作ったパスワードを検出の規則に一致しないだけで見落としたくもない。
8.2 検出すべきシークレットの種類
シークレットには多くの種類が存在し、すべてを正確に検出するためにそれぞれの特徴を検討するべきである。 一般的な種類には次のものがある。
- 高い可用性のシークレット(ローテーションが難しいトークン)
- アプリケーションの設定ファイル
- 接続文字列
- API キー
- 資格情報
- パスワード
- 二要素認証の鍵
- 秘密鍵(SSH の鍵など)
- セッションのトークン
- プラットフォーム固有のシークレットの種類(Amazon Web Services、Google Cloud など)
シークレットについてより楽しく学び、それを見つけ出す練習をするには Wrong Secrets のプロジェクトを参照する。
8.3 検出の生存期間
シークレットは他の認可のトークンと同じである。 次を満たすべきである。
- 必要な期間だけ存在する(頻繁にローテーションする)
- 自動ローテーションの手段を持つ
- 必要な者だけに見える(最小権限)
- 失効できる(失効したシークレットを使おうとする試行の記録を含む)
- 決して記録されない(平文のシークレットを記録しないよう、暗号化かマスクの方法を実装しなければならない)
シークレットの生存期間の各段階について検出の規則を作る。
8.4 シークレットの検出方法の文書
文書を作り定期的に更新し、組織で使える手続きとシステム、期待するシークレット管理の種類、シークレットの検査の方法、そしてシークレットが検出された場合に何をするのかを開発者のコミュニティへ伝える。
文書は次を満たすべきである。
- 存在し頻繁に更新される。とくに事故への対応として更新する。
- 次の情報を含める。
- 誰がそのシークレットへアクセスできるのか
- どうローテーションするのか
- シークレットのローテーションの最中に壊れうる上流や下流の依存関係
- 事故の際の連絡先
- 露出した場合の安全上の影響
- 脅威のリスクやデータの分類などに応じて、シークレットの扱いが変わりうる場合を特定する。
9 事故対応
シークレットが露出した場合の迅速な対応は、シークレット管理においておそらく最も重要な考慮点の一つである。
9.1 文書
シークレットが露出した場合の事故対応では、その管理の連鎖に関わる全員が把握し、どう対応するかを理解している状態にするべきである。 これはアプリケーションの作り手(開発チームの全員)、情報セキュリティ、そして技術の指導層を含む。
文書は次を含めなければならない。
- シークレットとその扱いをどう検査するか。とくに事業継続の見直しの際に。
- シークレットが検出されたとき誰に警報を出すか。
- 封じ込めのために採る手順。
- 事象の最中に記録する情報。
9.2 復旧
事故対応の主要な目的は、迅速な対応と封じ込めである。
封じ込めは次の手順に従うべきである。
- 失効。露出した鍵は直ちに失効させる。そのシークレットを迅速に認可から外せる必要があり、失効の状態を特定する仕組みを整えなければならない。
- ローテーション。新しいシークレットを迅速に作成し導入できなければならない。反復可能性、実装の誤りの少なさ、最小権限(人が直接読める形にしない)を確かにするため、望ましくは自動化された処理で行う。
- 削除。失効やローテーションを行ったシークレットは、露出したシステムから直ちに除去しなければならない。コードやログで見つかったシークレットも含む。コード内のシークレットは、そのシークレットが導入される前までコミットの履歴を圧縮できるが、これは git の履歴を書き換えるため他の問題を持ち込み、特定のコミットへの他のリンクを壊す。これを行うと決めるなら、その帰結を把握して計画する。ログ内のシークレットは、ログの完全性を保ちながらそのシークレットを除去する処理を持たなければならない。
- 記録。事故対応のチームは、封じ込めと復旧を助けるため、シークレットの生存期間についての情報へアクセスできなければならない。次を含む。
- 誰がアクセスできたか
- いつそれを使ったか
- 以前はいつローテーションされたか
9.3 記録
シークレットの使用の記録についての追加の考慮点を挙げる。
- 事故対応のための記録は、事故対応(IR)のチームがアクセスできる単一の場所に集めるべきである。
- パープルチームの演習などによって、記録される情報の忠実さを確かめる。
- 何が記録されているべきだったか。
- 実際に何が記録されたか。
- これを確かにする適切な警報が整っているか。
必要な情報がすべて記録される状態にするため、アプリケーションログの語彙のような標準化された記録の形式と語彙を使うことを検討する。
10 マルチクラウド環境におけるシークレット管理
10.1 はじめに
マルチクラウドの環境でシークレットを管理することは、クラウド事業者とそれぞれのサービスの多様さのため、独特の課題をもたらす。 この節は、複数のクラウド事業者にまたがってシークレットを管理するための課題と最良の慣行を論じる。
10.2 課題
- 多様な API とインタフェース。クラウド事業者はそれぞれシークレットを管理する独自の API とインタフェースを持ち、複数の事業者にまたがるシークレットの統合と管理に複雑さをもたらしうる。
- 一貫しない安全性の方針。クラウド事業者によって安全性の方針と慣行が異なりうるため、すべての環境で一貫した安全性の基準を強制することが難しくなる。
- 鍵のローテーション。複数のクラウド事業者にまたがって鍵が一貫して安全にローテーションされる状態にすることは難しくなりうる。とくに事業者ごとに鍵のローテーションの仕組みが異なる場合である。
- アクセス制御。複数のクラウド事業者にまたがるシークレットのアクセス制御の管理は複雑になりうる。事業者ごとにアクセス制御の仕組みと方針が異なりうるからである。
- 監査と監視。記録と監視の機能の違いのため、複数のクラウド事業者にまたがるシークレットのアクセスと使用の網羅的な監査と監視を確かにすることは難しくなりうる。
10.3 最良の慣行
- 集約されたシークレット管理の仕組みを使う。複数のクラウド事業者と統合できる集約されたシークレット管理の仕組みを実装する。これはシークレットの管理を標準化し、すべての環境で一貫した安全性の方針を強制する助けになる。例として HashiCorp Vault と CyberArk Conjur がある。
- 安全性の方針を標準化する。すべてのクラウド事業者にまたがるシークレット管理のための標準化された安全性の方針を定め、強制する。鍵のローテーション、アクセス制御、監査の方針を含む。
- 鍵のローテーションを自動化する。すべてのクラウド事業者にまたがって鍵が一貫して安全にローテーションされる状態にするため、自動の鍵のローテーションの処理を実装する。道具とスクリプトでローテーションの処理を自動化し、人為的な誤りのリスクを減らす。
- 細かい粒度のアクセス制御を実装する。最小権限の原則に基づいてシークレットへのアクセスを制限するため、細かい粒度のアクセス制御の仕組みを使う。アクセス制御の方針がすべてのクラウド事業者で一貫して強制される状態にする。
- 網羅的な監査と監視を有効にする。すべてのクラウド事業者にまたがるシークレットのアクセスと使用の網羅的な監査と監視を実装する。複数の事業者からのログを集約して分析するため、集約された記録と監視の仕組みを使う。