openai-security-ownership-map について
openai-security-ownership-map は、Git の履歴から人とファイルの関係グラフを作り、セキュリティ関連コードの所有リスクを分析するスキルです。リポジトリのセキュリティ確認向けに、グラフ出力と保守状況の検索機能を備えています。
主な機能
- 01Git 履歴から人・ファイルのグラフを作成
- 02ファイルの共変更関係とコミュニティを算出
- 03機密コードの所有リスクを検出
- 04CSV、JSON、任意の GraphML を出力
- 05範囲を限定した JSON 検索
活用シーン
- 01所有者が不明確な機密コードの特定
- 02bus factor の低いセキュリティ上の注目箇所の検出
- 03セキュリティ上の担当と CODEOWNERS の比較
- 04グラフデータの Neo4j または Gephi への取り込み
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trailofbits/ skills-curated --skill openai-security-ownership-mapインストール後、Claude Code で/openai-security-ownership-mapを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/neo4j-import.mdscripts/build_ownership_map.pycommunity_maintainers.pyquery_ownership.pyrun_ownership_map.py詳細
セキュリティ所有権マップ
概要
git 履歴から人物とファイルの二部グラフを構築し、所有権のリスクを算出して、Neo4j/Gephi 用のグラフアーティファクトをエクスポートします。あわせて、共通コミットに基づく Jaccard 類似度でファイルの共変更グラフを構築し、大規模でノイズの多いコミットを無視しながら、ファイルがどのように一緒に変更されるかに基づいてクラスタリングします。
要件
- Python 3
networkx(必須。コミュニティ検出はデフォルトで有効です)
インストール方法:
pip install networkx
ワークフロー
- リポジトリと期間を指定します(任意で
--since/--until)。 - センシティビティのルールを決定します(デフォルトを使用するか、CSV 設定ファイルを指定します)。
scripts/run_ownership_map.pyで所有権マップを構築します(共変更グラフはデフォルトで有効です。スーパーノードのコミットを無視するには--cochange-max-filesを使用します)。- コミュニティはデフォルトで計算されます。graphml 出力はオプションです(
--graphml)。 scripts/query_ownership.pyで出力をクエリし、範囲を限定した JSON スライスを取得します。- 永続化と可視化を行います(
references/neo4j-import.mdを参照)。
デフォルトでは、共変更グラフは一般的な「接着剤」となるファイル(ロックファイル、.github/*、エディター設定など)を無視します。これにより、クラスターは共有インフラの編集ではなく、実際のコードの変更を反映します。--cochange-exclude または --no-default-cochange-excludes で上書きできます。Dependabot のコミットはデフォルトで除外されます。上書きするには --no-default-author-excludes を使用するか、--author-exclude-regex でパターンを追加します。
Linux のビルド用グルーファイルである Kbuild を共変更クラスタリングから除外したい場合は、次のように指定します:
python skills/skills/security-ownership-map/scripts/run_ownership_map.py \
--repo /path/to/linux \
--out ownership-map-out \
--cochange-exclude "**/Kbuild"
クイックスタート
リポジトリのルートから実行します:
python skills/skills/security-ownership-map/scripts/run_ownership_map.py \
--repo . \
--out ownership-map-out \
--since "12 months ago" \
--emit-commits
デフォルトでは、作成者の識別情報、作成者の日付、マージコミットが除外されます。必要に応じて --identity committer、--date-field committer、または --include-merges を使用してください。
例(共変更の除外設定を上書き):
python skills/skills/security-ownership-map/scripts/run_ownership_map.py \
--repo . \
--out ownership-map-out \
--cochange-exclude "**/Cargo.lock" \
--cochange-exclude "**/.github/**" \
--no-default-cochange-excludes
コミュニティはデフォルトで計算されます。無効にするには:
python skills/skills/security-ownership-map/scripts/run_ownership_map.py \
--repo . \
--out ownership-map-out \
--no-communities
センシティビティのルール
デフォルトでは、一般的な認証・暗号・シークレット関連のパスにフラグが付けられます。CSV ファイルを指定して上書きできます:
# pattern,tag,weight
**/auth/**,auth,1.0
**/crypto/**,crypto,1.0
**/*.pem,secrets,1.0
--sensitive-config path/to/sensitive.csv と併用します。
出力アーティファクト
ownership-map-out/ には次のファイルが含まれます:
people.csv(ノード: 人物)files.csv(ノード: ファイル)edges.csv(エッジ: touches)cochange_edges.csv(Jaccard 重み付きのファイル間共変更エッジ。--no-cochange指定時は省略されます)summary.json(セキュリティ所有権の調査結果)commits.jsonl(任意。--emit-commits指定時)communities.json(利用可能な場合、共変更エッジからデフォルトで計算されます。各コミュニティのmaintainersを含みます。--no-communitiesで無効化できます)cochange.graph.json(community_idとcommunity_maintainersを含む NetworkX のノードリンク JSON。共変更エッジがない場合はownership.graph.jsonにフォールバックします)ownership.graphml/cochange.graphml(任意。--graphml指定時)
people.csv には、作成者のコミットオフセットに基づくタイムゾーン検出の結果が含まれます: primary_tz_offset、primary_tz_minutes、timezone_offsets。
LLM 向けクエリヘルパー
scripts/query_ownership.py を使用すると、グラフ全体をコンテキストに読み込まずに、JSON で範囲を制限した小さなスライスを取得できます。
例:
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out people --limit 10
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out files --tag auth --bus-factor-max 1
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out person --person alice@corp --limit 10
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out file --file crypto/tls
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out cochange --file crypto/tls --limit 10
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out summary --section orphaned_sensitive_code
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out community --id 3
コミュニティごとに保存するメンテナーの数は --community-top-owners 5(デフォルト)で制御します。
基本的なセキュリティクエリ
次のコマンドを実行すると、一般的なセキュリティ所有権の質問に、出力を制限した形で回答できます:
# Orphaned sensitive code (stale + low bus factor)
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out summary --section orphaned_sensitive_code
# Hidden owners for sensitive tags
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out summary --section hidden_owners
# Sensitive hotspots with low bus factor
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out summary --section bus_factor_hotspots
# Auth/crypto files with bus factor <= 1
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out files --tag auth --bus-factor-max 1
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out files --tag crypto --bus-factor-max 1
# Who is touching sensitive code the most
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out people --sort sensitive_touches --limit 10
# Co-change neighbors (cluster hints for ownership drift)
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out cochange --file path/to/file --min-jaccard 0.05 --limit 20
# Community maintainers (for a cluster)
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out community --id 3
# Monthly maintainers for the community containing a file
python skills/skills/security-ownership-map/scripts/community_maintainers.py \
--data-dir ownership-map-out \
--file network/card.c \
--since 2025-01-01 \
--top 5
# Quarterly buckets instead of monthly
python skills/skills/security-ownership-map/scripts/community_maintainers.py \
--data-dir ownership-map-out \
--file network/card.c \
--since 2025-01-01 \
--bucket quarter \
--top 5
注記:
- touches はデフォルトで作成コミット 1 件につき 1 回とカウントされます(ファイルごとではありません)。ファイルごとにカウントするには
--touch-mode fileを使用します。 - 変更の偏りを平滑化するには
--window-days 90または--weight recency --half-life-days 180を使用します。 - ボットは
--ignore-author-regex '(bot|dependabot)'で除外します。 - 安定して関わっているメンテナーのみを表示するには
--min-share 0.1を使用します。 - 暦四半期ごとのグループ化には
--bucket quarterを使用します。 - 作成者による帰属から切り替えるには
--identity committerまたは--date-field committerを使用します。 - マージコミットを含めるには
--include-mergesを使用します(デフォルトでは除外されます)。
サマリーの形式(デフォルト)
次の構造を使用してください。必要に応じてフィールドを追加できます:
{
"orphaned_sensitive_code": [
{
"path": "crypto/tls/handshake.rs",
"last_security_touch": "2023-03-12T18:10:04+00:00",
"bus_factor": 1
}
],
"hidden_owners": [
{
"person": "alice@corp",
"controls": "63% of auth code"
}
]
}
グラフの永続化
CSV を Neo4j に読み込む必要がある場合は、references/neo4j-import.md を使用してください。制約、インポート用の Cypher、可視化のヒントが含まれています。
注意事項
summary.jsonのbus_factor_hotspotsには、バス係数が低い機密ファイルが一覧表示されます。orphaned_sensitive_codeはそのうち古くなったものです。git logの出力が大きすぎる場合は、--sinceまたは--untilで対象を絞り込みます。summary.jsonを CODEOWNERS と比較して、所有者の乖離を明らかにします。