threat-modeling について
Bitwarden のエンジニアリングチーム向け脅威モデリングスキルで、初期セキュリティ評価を中心に後続のレビューや検証も支援します。STRIDE、データフロー図、Bitwarden のセキュリティ定義を用い、脅威の範囲と目標の整合性を重視します。
主な機能
- 01Mermaid データフロー図の作成
- 02STRIDE による脅威の特定
- 03セキュリティ定義と目標の作成
- 04アーキテクチャ決定との整合性確認
- 05目標の状態とリスクの評価
活用シーン
- 01新サービスの初期評価
- 02サービス間のデータフローと信頼境界の整理
- 03AppSec レビュー資料の準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bitwarden/ ai-plugins --skill threat-modelingインストール後、Claude Code で/threat-modelingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
examples/data-flow-diagram.mdsecurity-definition-document.mdthreat-catalog.mdreferences/bitwarden-vocabulary.mdsecurity-principles.mdstride-framework.mdwriting-quality-sds.md詳細
Bitwardenのエンゲージメントモデル
Bitwardenは、セキュリティ業務に4段階のエンゲージメントモデルを採用しています。このスキルは主にフェーズ1(エンジニアリングチーム主導)を支援し、フェーズ2〜4の成果物の作成も補助します。
フェーズ1:初期セキュリティ評価(エンジニアリングチーム)
- Bitwardenのアーキテクチャ決定記録を確認し、レビュー対象のシステムやコンポーネントに関する既存の決定を確認します(
${CLAUDE_PLUGIN_ROOT}/references/adr-alignment.mdを参照)。脅威モデルは、すでに承認されたアーキテクチャと整合させる必要があります。既存の内容を暗黙のうちに再導出したり、矛盾したりしてはいけません。 - データフロー図(Mermaid)を作成します。
- セキュリティ要件をプロダクト要件とは分けて定義します。
- セキュリティ定義(脅威モデルとセキュリティ目標)を提案します。
- STRIDEを使用して初期脅威を特定します(
references/stride-framework.mdを参照)。
フェーズ2:AppSecチームによるレビュー(AppSecチーム+エンジニアリングチーム)
- データフロー図とセキュリティ定義を事前に共有します。
- システムアーキテクチャを共同で確認します。
- 提案されたセキュリティ定義を検証または精緻化します。
- 追加の脅威を特定し、リスクを評価します。
- 外部の緩和策が存在すると想定しないようにします。
フェーズ3:実装(エンジニアリングチーム)
- 必要なセキュリティ緩和策を実装します。
- 既存の保護策がない脅威について、Jiraでフォローアップ作業を作成します。
- スプリント計画にセキュリティ上の考慮事項を含めます。
フェーズ4:テストと検証(エンジニアリングチーム+AppSecチーム)
- 緩和策が意図したとおりに機能することを検証します。
- コードレビューでは、敵対者の視点を取り入れます。
- 逆算して仮説(例:「SSOを回避できるか?」)をテストします。
- システムの進化に合わせてセキュリティ定義を更新します。
セキュリティ定義
セキュリティ定義(SD)は、システムのセキュリティ態勢を伝えるためのBitwardenの正式な枠組みです。各定義は、脅威モデル(攻撃者の能力)、セキュリティ目標(システムが保証する内容)、受け入れ済みの目標ステータス(目標が現在達成されているかどうかの率直な評価)の3つの要素で構成されます。
定義を記述する際は、Bitwardenの標準用語を使用してください。用語集全体についてはreferences/bitwarden-vocabulary.mdを参照してください。セキュリティ目標は、Bitwardenのセキュリティ原則(P01-P06)に沿わせてください。詳細はreferences/security-principles.mdを参照してください。
脅威モデルのコンポーネント
攻撃者の能力と制限、つまり攻撃者にできることとできないことを記述します。定義の範囲を正確に定めるため、必ず両方を明記してください。
- 「攻撃者は、ユーザーのクライアントがログアウトした後にユーザー空間プロセスを実行できる」+「攻撃者はセキュアストレージ機構にアクセスできない」
- 「攻撃者はデータベースにアクセスでき、Send テーブルの読み取りと書き込みができる」+「攻撃者は ASP.NET Core Data Protection の暗号化キーにアクセスできない」
必要に応じて、具体例を含めてください(例:「デバイスが盗まれた場合がこれに該当します」)。外部の緩和策が講じられていると仮定しないでください。認証トークンの取得が困難な場合でも、攻撃者がトークンを持っていたら何が起こるかを検討してください。
脅威モデルの範囲を定める際は、次のルールを適用してください。
- 支配される脅威を除外します。 記述している攻撃者の能力が、すでに範囲外として認められている能力より明らかに弱い場合は、その SD を削除してください。残余リスクの記述が「ユーザーアカウントが完全に侵害された場合と同等」のような同語反復に陥るためです。支配される脅威のアンチパターンと、
references/bitwarden-vocabulary.mdの 支配される脅威 という用語については、references/writing-quality-sds.mdを参照してください。 - 敵対者だけでなく、受動的な観察者も含めます。 秘密情報や保護対象データが外部サービス(LLM プロバイダー、ログ集約サービス、分析パイプライン、トレーニングデータ収集者)に渡る場合は、攻撃者が善意だが好奇心旺盛な SD を少なくとも 1 つ作成してください。機密性に関する被害は、多くの場合、悪意ではなく 可視性 から生じます。敵対者を想定しただけでは、基本的な懸念を見落とします。「受動的な観察者」の用語項目を参照してください。
- 「攻撃者は X にアクセスできない」という前提を、対象プラットフォームで検証します。 すべての制限は、対象範囲のすべての OS/ランタイムで事実に即している必要があります。よくある落とし穴は、実際には Linux や Windows で特権なしに可能な操作(別のプロセスの環境変数の読み取りなど)に、カーネルレベルの特権が必要だと思い込むことです。その制限が事実でない場合、SD の範囲設定は不適切です。
セキュリティ目標のコンポーネント
脅威モデルに基づいて発生し得ない事象について、簡潔で検証可能な保証を記述します。トークン、キー、保管庫データなど、具体的な資産を明記してください。
- 「ユーザーのクライアントがログアウトした後、攻撃者は有効なトークンにアクセスできない」
- 「攻撃者は、自分に属さない復号済み MasterKey を取得できない」
- 「攻撃者が実行できるのは、暗号化されたメールアドレス一覧の読み取りだけである」
各目標には、3 つの要素をそれぞれ 1 行で記述した根拠が必要です。
- 原則 — 目標が実現する Bitwarden の原則(P01~P06)。
references/security-principles.mdを参照してください。 - 資産 — 保護対象となる具体的なデータ、キー、またはトークン。
- 被害 — 目標に違反した場合にユーザーに及ぶ影響(例:「マスターパスワードがサードパーティの LLM プロバイダーに露出し、そのトレーニングパイプラインにも送られる可能性がある」)。
根拠のない目標は要件ではなく、単なる主張です。根拠があれば、レビュー担当者はその目標が不可欠なのか、削除できるのかを判断できます。
目標の設定に関する追加ルールは次のとおりです。
- ランタイムに照らして目標の現実性を確認します。 秘密情報を「メモリから消去する」「ゼロ化する」「保持しない」とする目標は、ガベージコレクションを行う、文字列をインターンするランタイム(JavaScript、.NET、JVM、Python)では強制できません。ランタイムが目標を保証できない場合は、ランタイムが 保証できる 内容(スコープの最小化、参照の短命化、プロセス分離)に言い換えるか、Accepted Goal Status が明示的に未達であることを示し、システム上の制約へのリンクを記載してください。言語が保証できない目標を記述しないでください。
- 秘密情報の受け渡しには、環境変数や argv より stdin またはファイル記述子を優先します。 目標で秘密情報を
process.envまたはargvに露出させないことを求める場合、実装では MUST stdin または継承されたファイル記述子を使用してください。目標では環境変数への露出を禁じているのに、実装では環境変数を介して秘密情報を渡す SD は、内部的に矛盾しています。設計か目標のどちらかを修正し、両方をそのまま出荷しないでください。
受け入れ済みの目標ステータスコンポーネント
現在の状態を正直に評価します。
- 目標は達成されています — その方法を説明します(例:「ユーザー状態のクリアには、保存されたトークンをディスクから削除する処理が含まれます」)
- 目標は部分的に達成されています — 各側面について、機能する点と機能しない点を分けて示します
- 目標は達成されていません — 不足している点と、それが許容される理由を説明します
- ベストエフォート — プラットフォームの機能に依存する目標について示します(例:「Web やブラウザーなど、安全なストレージにアクセスできないクライアントでは、この目標は保証されません」)
既知の不具合がある目標については、該当する追跡課題へのリンクを記載します。適用範囲に関する注意事項も記載します(例:Never に設定された Vault Timeout の場合、これらの定義は適用されません)。
追加ルールが 2 つあります。
- 「短時間」や「短期間」を根拠とする場合は、定量化してください。 残存リスクを受け入れる理由が「露出が短時間である」ことに基づくなら、その上限を明記します。たとえば、「シークレットは
bw unlockの実行中、子プロセスの環境変数に存在します。この時間は KDF の反復回数と Vault のサイズに応じて変わり、代表的なハードウェアでは 1~8 秒の範囲で観測されています。」とします。数値を伴わない「短時間」は、受け入れ可能なステータスではなく、単なる期待です。「露出期間」の用語項目を参照してください。 - 内部整合性を確保してください。 脅威モデル、セキュリティ目標、受け入れ済みの目標ステータスの内容を一致させます。脅威モデルで機能 X を対象範囲に含めるなら、目標は X への対策を求め、ステータスにはその対策が機能するかどうかを記載します。目標が環境変数への露出を禁止している一方で、実装が環境変数を使用しているなら、SD は誤りです。3 つのうちどれを変更するかを決め、変更してください。整合性の欠如は文体上の問題ではなく、SD がシステムを正しく記述できていないということです。
セキュリティ定義の作成
- 間違っていても問題ありません。目的は、議論を始め、定義が破られる可能性を確かめることです。
- システムが保証すべきことから始め、その後、脅威分析を通じて検証します。
- エンドツーエンド暗号化のようなマクロレベルの定義と、機能に固有のミクロレベルの定義を分けます。
- 定義には SD1、SD2、SD3 のように順番に番号を付けます。それぞれ単独で意味が通じるものにします。
- 機能にその領域固有の用語が導入される場合は、その用語の用語集を追加します。
- 列挙順ではなく、影響度を優先してください。 設計を実際に左右する脅威を 3~5 件記載した短い文書は、重要な内容が雑多な情報に埋もれた SD 15 件の文書よりも有用です。SD を追加する前に、次のように考えてください。「この脅威が存在しなかったとしても、設計は変わるだろうか?」 答えが「いいえ」なら、それはセキュリティ定義ではなく、コード品質に関する解説である可能性が高いです。
- 各 SD に重要度レベル(Critical/High/Medium/Low)を付け、重要度の高い順に文書を並べます。これにより、レビュー担当者は設計を支える重要な SD を最初に確認できます。優先順位付けのヒューリスティックについては、
references/writing-quality-sds.mdを参照してください。 - 冗長さは失敗の原因になります。 初期の LLM コードレビューで問題となった、情報量の少ない長いリストというアンチパターンは、生成されたセキュリティ定義にも見られます。設計を支える重要なものでない限り、実装の詳細に関する懸念(たとえば、将来の保守担当者が定数を編集してシェルのメタ文字を含めてしまうこと)を記述した SD は削除してください。
アーティファクトの生成
アーティファクトを生成する際は、examples/ のテンプレートを使用します。
examples/security-definition-document.md— 用語集、番号付き定義、重要度のタグ付け、目標の根拠、承認済み目標のステータスを含む、SD ドキュメントの完全なテンプレートexamples/data-flow-diagram.md— 信頼境界を含む Mermaid DFD テンプレートexamples/threat-catalog.md— 脅威カタログの表と、緩和策を追跡するテンプレート
SD の作成やレビューでは、以下のリファレンスを参照してください。
references/writing-quality-sds.md— アンチパターン(支配的な脅威、攻撃者を敵対的な存在のみに限定すること、強制できない目標、願望にすぎない制限、シェルの引用処理に関する SD、「短時間の露出」という落とし穴)と、自己整合性チェックリストreferences/bitwarden-vocabulary.md— 受動的な観察者、支配的な脅威、露出ウィンドウなどの標準用語references/security-principles.md— すべての目標の「根拠」行で参照される P01~P06references/stride-framework.md— 構造的な脅威の特定に使用する STRIDE カテゴリー${CLAUDE_PLUGIN_ROOT}/references/adr-alignment.md— security-engineer スキル間で共有される、アーキテクチャ決定記録の整合性チェック
AppSec への相談が必要な場合
チームは、次の場合に AppSec チーム(#team-eng-appsec)との本格的な相談を開始してください。
- 新規プロジェクトまたは新しいサービス
- データ共有の変更(組織のメンバーシップ、Send、共有機能)
- コンポーネント間の新しい IPC チャネル
- 異なるドメイン間またはオリジン間の機能
- セキュリティへの影響が不明な場合 — まず初期セキュリティ評価を実施し、本格的な相談が必要か不明であることを添えて、調査結果を #team-eng-appsec に投稿してください
サードパーティライブラリやコーディング手法への懸念などの簡単な質問に、本格的な相談は必要ありません。直接 #team-eng-appsec に投稿してください。
重要なルール
- 技術的な内訳では、製品要件とセキュリティ要件を分けてください。これらは目的も関係者も異なります。
- セキュリティ定義は、継続的に更新されるドキュメントです。 機能が変更された場合、新たな脅威が発生した場合、またはセキュリティ上の問題が見つかった場合は、内容を見直してください。
- 複雑さは脆弱性のリスクを高めます。 セキュリティ上重要なコードが過度に複雑な場合は、技術的負債として指摘してください。依存関係が多く、ロジックが複雑なコードのセキュリティを確保するのは、非常に困難です。
- 脅威モデリングですべての脆弱性を特定することはできません。 脅威モデリングは多くの手法のうちの一つです。コード分析、セキュリティテスト、敵対的レビューと組み合わせて活用してください。
- 外部の緩和策を前提にしないでください。 脅威モデルを定義する際は、攻撃者が外部の制御を回避した場合に何が起こるかを検討してください。
- 支配的な脅威や、実装上ほとんど問題にならない脅威はノイズです。 残余リスクの説明が「ユーザーアカウント全体の侵害と同等」に帰着する SD や、唯一の緩和策が「レビュー担当者が定数の編集に気づくこと」である SD は削除してください。これらはシグナル対ノイズ比を悪化させ、本当に重要な脅威を見えにくくします。
- すべてのセキュリティ目標には根拠が必要です。 各目標を Bitwarden の原則(P01~P06)、保護対象の資産、ユーザーに見える被害に結び付けてください。根拠のない目標は優先順位付けや必要性の評価ができず、妥当性ではなく惰性によってレビューを通過しがちです。
SD の一式を確定する前に、references/writing-quality-sds.md の自己整合性チェックリストを適用してください。