security-ownership-map について
security-ownership-map は Git 履歴から人とファイルの所有権グラフを作成し、コードの責任体制を調べるチーム向けにセキュリティリスクを算出します。共同コミットによるファイルのクラスタリングや、クエリ・可視化用のグラフ出力にも対応します。
主な機能
- 01人とファイルの所有権グラフ作成
- 02機密コードの所有権リスク検出
- 03共同コミットによるファイル分類
- 04コミュニティ計算とグラフ出力
- 05範囲を限定した JSON クエリ
活用シーン
- 01担当者の少ない機密ファイルの発見
- 02長期間未保守の機密コードの特定
- 03連動して変更されるファイルと担当者の分析
- 04Neo4j または Gephi へのグラフデータ取り込み
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tech-leads-club/ agent-skills --skill security-ownership-mapインストール後、Claude Code で/security-ownership-mapを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.txtreferences/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 でパターンを追加できます。
共変更クラスタリングから Kbuild などの Linux ビルド関連ファイルを除外するには、次を渡します:
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
デフォルトでは、著者の ID と日付を使用し、マージコミットは除外されます。必要に応じて --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(エッジ:変更)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
注意:
- 変更数はデフォルトで、ファイルごとではなく、著者が作成したコミット数として集計されます。ファイルごとの変更数を数えるには
--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 と比較して、オーナーシップのずれを明らかにしてください。