mantis-threat-model について
Mantisのアーキテクチャとエンティティのナレッジベースから、高レベルの脅威モデルを作成・管理するfindings-onlyスキルです。信頼境界、攻撃者像、高リスク資産を記述し、スナップショットの来歴を追跡して、更新前に旧モデルを保存します。
主な機能
- 01ナレッジベースのアーキテクチャとエンティティを読み込み
- 02信頼境界と攻撃経路を特定
- 03高リスク資産と可用性ティアを記録
- 04スナップショットの来歴と鮮度を追跡
- 05旧脅威モデルをアーカイブ
活用シーン
- 01既存のアーキテクチャナレッジベースから脅威モデルを作成
- 02ナレッジベースのスナップショット変更後にモデルを再導出
- 03各パスの旧モデルを保存してレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ google/ mantis --skill mantis-threat-modelインストール後、Claude Code で/mantis-threat-modelを入力して読み込まれたか確認します。
詳細
Threat Modeler (/mantis-threat-model)
システムの目標
セキュリティアーキテクトです。ナレッジベース(KB)で定義されたエンティティとアーキテクチャのみを基に、信頼境界、攻撃対象領域、攻撃者プロファイルを統合し、THREAT_MODEL.md を作成します。
コマンドの定義
- コマンド:
/mantis-threat-model - 説明: アーキテクチャの境界、エントリーポイント、信頼境界を評価して、脅威モデルを作成します。
- 引数(すべて任意。省略時は今日の動作になります):
--state_root <dir>:workspace/の親ディレクトリです。省略した場合は、カレントディレクトリからの相対パス./workspace/...を使用します。.mantis_state.json、KB、アーカイブディレクトリの場所を特定します。--snapshot_id <id>:この処理を固定するSNAPSHOT_IDです。THREAT_MODEL.mdに記録される来歴値(KB_SNAPSHOT:行)としてのみ使用します。省略した場合は、state のactive_snapshot.snapshot_idにフォールバックします。それも存在しない場合、またはsnapshot_pinnedが false の場合、記録値は文字列UNPINNEDになります。--snapshot_root <dir>:インターフェースの統一のために受け付けますが、使用しません。このステージでは対象のソースを読み込みません(Block A の step 0、調査結果のみを扱う役割)。
入出力コントラクト
- 読み込み対象:
workspace/.mantis_state.json—pass_number(パスごとのアーカイブ用)と、来歴のためだけに使用するactive_snapshot({root, snapshot_id, snapshot_pinned})。どちらも任意です。存在しない場合は、機能が縮退します(後方互換性を参照)。workspace/kb/architecture.md。workspace/kb/entities/*.md。- 以前のパスで作成された
workspace/kb/THREAT_MODEL.md(存在する場合)。step 0 の鮮度チェックに使用するのは、最初のKB_SNAPSHOT:行のみです。
- 書き込み対象:
workspace/kb/THREAT_MODEL.md(1 行目はKB_SNAPSHOT:の来歴ヘッダーです)。- 上書きする前に、以前の
workspace/kb/THREAT_MODEL.md(存在する場合)をworkspace/archive/kb/THREAT_MODEL_pass_${N}.mdにアーカイブします。
- 前提条件:
- ナレッジベースのファイルが存在し、内容が入力されている必要があります。
- 冪等性の保証:
- 以前の
THREAT_MODEL.md(存在する場合)をパスのアーカイブにコピーした後、workspace/kb/THREAT_MODEL.mdをその場で決定論的に上書きします。スナップショットが変わらない状態で同じパスを再実行すると、同等のモデルが生成され、STALEバナーが付加されます(step 0 と最後の保存ステップを参照)。
- 以前の
手順
LOCATOR RESOLUTION (before reading ANY target code or artifact):
0. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
state for provenance/annotation; NEVER stop merely because a code root is unset.
1. Determine CODE_ROOT, in this priority order:
a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
(used when a caller hands you a prepared tree, e.g. a patched shadow).
b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
c. Else read state_root/workspace/.mantis_state.json (state_root from
--state_root if passed, else ./workspace/... relative to the current dir)
-> active_snapshot.root / .snapshot_id / .snapshot_pinned.
d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
2. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
deliberately mutated and is sentinel-EXEMPT.)
3. PATH FIELDS:
- SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
NOT of the form <existing-path>:<integer> is a non-source LOCATOR
(symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
line-range and line-existence logic.
- STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
kb_references, repro_file_path, reattack_file_path, helper scripts, report
files, and all state/findings JSON.
4. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
(mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
cd into CODE_ROOT.
5. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
(the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
lacks .git/.hg/.repo.
6. Every shell command uses ABSOLUTE paths and sets its own working directory on
that call. Do NOT assume the working directory persists between calls.
このステージの役割(調査結果のみ/KB のみ)。 /mantis-threat-model は対象のソースを読み込みません。使用するすべての入力(architecture.md、entities/*.md、以前の THREAT_MODEL.md、.mantis_state.json)は state 相対です(state_root/workspace 配下から読み込み、CODE_ROOT 配下からは決して読み込みません)。したがって、このステージでは Block A の step 0 にある「調査結果のみ」の経路を使用します。Block A の step 2〜6 はスキップしますが、来歴情報のために state から active_snapshot は読み込み、コードルートが未設定または未固定であることだけを理由に処理を中止することは決してありません。
KB 内の前処理済みエンティティを基に、攻撃者が「誰」であり、システムの「どこ」とやり取りできるのかを明確に定義した、高レベルの脅威モデルを維持してください。
次の手順で脅威モデリングを実行します。
-
スナップショットの来歴と鮮度を確認し、以前のモデルをアーカイブする:
a.
CUR(この脅威モデルが記録される対象のスナップショット)を計算します:--snapshot_idが渡された場合 →CUR= その値。- それ以外で、state の
active_snapshot.snapshot_pinnedが true の場合 →CUR=active_snapshot.snapshot_id。 - それ以外の場合 →
CUR= 文字列UNPINNED(機能が縮退した状態/今日の動作)。
b.
PREV_TM(前回のモデルが記録された対象)を計算します: 既存のworkspace/kb/THREAT_MODEL.mdで^KB_SNAPSHOT:に一致する最初の行を読み込み、その値(前後の空白を削除したもの)をPREV_TMとします。ファイルが存在しない場合、一致する行がない場合、または値が空の場合は、PREV_TM= 空文字列""とします。c. 同期差分の判定(機械的に実行。文字列の完全一致で比較し、あいまいな比較は行いません):
CUR == "UNPINNED"→SYNC_OCCURRED = true(デグレード: 常に再導出)。- それ以外で
PREV_TM == ""→SYNC_OCCURRED = true(初回実行 / レガシー KB)。 - それ以外で
PREV_TM != CUR→SYNC_OCCURRED = true(同期またはダーティ編集により スナップショットが進んだ)。 - それ以外 (
PREV_TM == CUR) →SYNC_OCCURRED = false(スナップショットは前回のモデル以降 変更されていない)。
d. 以前のモデルをアーカイブする (パスごと)。これにより上書きが非破壊的になります:
Nを解決します:workspace/.mantis_state.jsonから"pass_number"を読み取ります。存在しないか 無効な場合は、workspace/archive/をスキャンしてfindings_pass_NまたはloopN_findingsに 一致するフォルダーを探し、N = max_found + 1を設定し、アーカイブが存在しない場合は デフォルトで1とします。(アーキテクチャステージが使用するのと同じルールです。)workspace/kb/THREAT_MODEL.mdが存在する場合:workspace/archive/kb/の存在を確認し (mkdir -p workspace/archive/kb/)、そのファイルを COPY (移動はしない) してworkspace/archive/kb/THREAT_MODEL_pass_${N}.mdに配置します。ステップ 3 で ライブファイルを上書きします。ファイルが存在しない場合は、コピーをスキップします。- このステップのすべてのパスは STATE-RELATIVE (
state_root/workspace配下) です。CODE_ROOTを決してプレフィックスしないでください。
CUR、SYNC_OCCURRED、Nをステップ 1~3 および最終保存に引き継いでください。 -
合成された KB を読み取る:
workspace/kb/architecture.mdを読み取り、システムのデータフローと 高レベルの設計を理解します。workspace/kb/entities/内のファイルを読み取り、個々の コンポーネントと、/mantis-architectureステージによってそれらにマッピングされた 過去の制約や脆弱性パターンを理解します。
-
信頼境界を分析する:
- エンティティを評価して、信頼境界がどこにあるかを判断します。信頼されていないデータは どこで信頼されたコンテキストに侵入しますか? どのコンポーネントが外部入力に さらされていますか?
-
脅威モデルを合成する:
- 包括的で構造化された Markdown ファイルを作成し、
workspace/kb/THREAT_MODEL.mdに直接保存します (古いものを上書きします)。 - トークン最適化: ファイル書き込みツールを使用してファイルを ディスクに直接書き込みます。脅威モデルのテキストをチャット 応答に出力しないでください。
下流のプランニングエージェントが十分なコンテキストを得られるよう、以下のセクションを 含めてください:
-
システム概要サマリー:
architecture.mdから導出された簡潔な サマリー。 -
デプロイの意図:
Intent: PRODUCTIONまたはIntent: SAMPLE_OR_TEST_ONLYの いずれか一方を正確に記述します。この判定は影響範囲が大きくなります:/mantis-criticはIntent: SAMPLE_OR_TEST_ONLYを読んだ瞬間に、 すべての所見をSAMPLE_OR_TESTとしてマークし (パス全体を却下します)。したがってSAMPLE_OR_TEST_ONLYは機械的なチェックリストの背後で FAIL-CLOSED となります:PRODUCTION-SIGNAL CHECKLIST —
Intent: SAMPLE_OR_TEST_ONLYを記述できるのは、 5 つのチェックすべてが TRUE の場合のみです。いずれかが FALSE の場合、または KB が それについて沈黙している / いずれかについて確信がない場合は、Intent: PRODUCTIONを記述しなければなりません。workspace/kb/entities/*.md内のエンティティに、CRITICALまたはSTANDARDの可用性分類が付与されていないこと(いずれも稼働中/本番環境のサービスを意味します)。architecture.mdに、外部から到達可能なサービス、デーモン、サーバー、 API、ネットワークエンドポイントが一切記載されておらず、デプロイ/パッケージング記述子 (systemd、Dockerfile/docker、kubernetes/k8s/helm、ロードバランサー、 クラウド/VPC/IaC、CI/CD の公開またはリリース)も一切記載されていないこと。- KB に、インストール可能/公開可能なパッケージやランタイムの
エントリーポイント(例:
console_scripts/entry_points、main()/サービス バイナリ、公開済みライブラリ、パッケージマニフェスト)が一切記載されていないこと。 - KB で参照されるすべてのコンポーネント/パスが、テスト/サンプル用ディレクトリ内だけに存在すること —
パスに
test、tests、example、examples、sample、samples、tutorial、demo、docs、fixturesのいずれかが含まれ、本番ソースのルート(src、lib、pkg、internal、cmd、app、server、coreなど)には一切含まれないこと。 - 実際の(モックでもテスト用でもない)信頼されていない外部入力が、信頼境界を越えて 特権/本番ロジックに到達することを記載したエンティティがないこと。
同期後(ステップ 0 で
SYNC_OCCURRED == true)は、現在の KB を対象に、この チェックリストを最初から必ず再実行し、以前のIntent:判定を引き継がないでください — 同期によって、以前はサンプルのみだったツリーに本番コードが追加される可能性があり、 そうしなければ新たな指摘がすべて気付かれないまま除外されてしまうためです。 -
信頼境界: 信頼されていない入力が、信頼された内部状態と接する場所を、明確かつ厳密に定義します。具体的なエンティティを参照してください(例:
[Auth Module](entities/auth_module.md))。 -
脅威アクターと攻撃経路: 潜在的な攻撃者のプロファイル(例:未認証のネットワーク攻撃者、悪意のあるローカルユーザー)と、到達可能な具体的な境界を定義します。
-
高リスク資産: 攻撃者が侵害を狙うデータ、実行権限、または可用性の対象です。可用性の対象については、KB に基づいて次の可用性ティアのいずれかに分類してください:
CRITICAL:中断された場合、24 時間 365 日、即座に運用上の影響が発生します。STANDARD:重要な業務です。短時間の停止は許容されます。LOW_CRITICALITY:業務を妨げないユーティリティです。中断されても軽微な不便が生じる程度です。
- 包括的で構造化された Markdown ファイルを作成し、
モデルにスタンプを付けて保存します:
workspace/kb/THREAT_MODEL.mdの最初の行には、来歴スタンプとしてKB_SNAPSHOT:に続けて(ステップ 0 の)CURを必ず記載します — 例:KB_SNAPSHOT: <CUR>、 または縮退モードではKB_SNAPSHOT: UNPINNED。次のパスではこれを読み戻してPREV_TMとし、mantis-criticはこれを KB の鮮度チェックとして読み取ります。SYNC_OCCURRED == false(前回のモデル以降スナップショットに変更がない)の場合:以前のモデルの内容を再利用してもかまいませんが、KB_SNAPSHOT:行の直後の行に、次の STALE バナーを必ず挿入してください:> STALE: Threat model NOT re-evaluated this pass; carried unchanged from snapshot <CUR>.SYNC_OCCURRED == trueの場合:STALE バナーは出力しないでください — デプロイ意図チェックリストを含むすべてのセクションを、このパスで新たに導出します。workspace/kb/THREAT_MODEL.mdに直接保存します(状態相対パス — 前のファイルはステップ 0d でパスアーカイブにすでにコピーされています)。ファイル書き込みツールを使用してください。モデルをチャットに出力しないでください。完了したらユーザーに通知してください。