用 security-ownership-map 從 Git 歷史畫出安全責任拓撲

前言

很多團隊都有 CODEOWNERS,也有人會臨時跑一下 git blame。真正出事時,問題往往不是「文件寫在誰名下」,而是:認證、加密、密鑰相關代碼到底還有沒有人在維護?Bus Factor 是不是低到只剩一個人?紙面責任和提交歷史是否已經脫節?

security-ownership-map 就是爲這類「安全向所有權」問題準備的 Agent Skill。它基於 Git 歷史構建人與文件的二部圖,計算敏感代碼的 Bus Factor,導出 CSV/JSON,並可導入 Neo4j、Gephi 做可視化。本文按官方 SKILL.md 與腳本說明,介紹它是什麼、怎麼裝、怎麼用。

這是什麼

security-ownership-map 來自 OpenAI 的 Agent Skills 目錄倉庫 openai/skills 中的 curated 技能,路徑爲 skills/.curated/security-ownership-map。它遵循通用的 SKILL.md 格式,可在 Codex、Cursor、Claude Code 等支持 Agent Skills 標準的工具中使用。

官方對它的定位很明確:只在用戶明確要做安全向所有權或 Bus Factor 分析時觸發,例如孤兒敏感代碼、安全維護者識別、對照 CODEOWNERS 做風險覈對、敏感熱點、所有權聚類等;不要拿它回答普通的「誰是維護者」類問題。

需要說明:openai/skills 倉庫 README 已標註 deprecated,新的 Codex skill / plugin 示例轉向 openai/plugins。當前仍可從原 curated 目錄獲取該 Skill 的 SKILL.md、腳本與參考文檔。

核心功能與亮點

根據官方說明,主要能力包括:

  1. 人–文件二部圖:從 Git 歷史構建 people ↔ files 拓撲,刻畫「誰碰過哪些文件」。
  2. 敏感代碼與 Bus Factor:默認識別常見 auth / crypto / secrets 路徑,計算所有權風險;summary.json 中會給出 bus_factor_hotspotsorphaned_sensitive_codehidden_owners 等安全向結論。
  3. 共變圖(co-change):按共享提交的 Jaccard 相似度聚類「經常一起改動」的文件;默認忽略 lockfile、.github/*、編輯器配置等「膠水文件」,並默認排除 Dependabot 類提交,減少噪聲。
  4. 社區檢測:依賴 networkx,默認計算 community,併爲每個社區給出 maintainers。
  5. 可查詢、可導出:輸出 CSV/JSON(可選 GraphML),再用 query_ownership.py 按需取小塊 JSON,避免把整張圖塞進模型上下文;需要持久化時可按 references/neo4j-import.md 導入 Neo4j。

依賴很簡單:Python 3,以及:

pip install networkx

安裝與啓用

Codex

在 Codex 裏可用內置的 $skill-installer 安裝 curated 技能(默認對應 skills/.curated):

$skill-installer security-ownership-map

也可直接給出 GitHub 目錄 URL。安裝後需重啓 Codex 以加載新 Skill。

Cursor / Claude Code 等

Skill 本體是一個目錄,核心是 SKILL.md,並附帶 scripts/references/ 等。按 Agent Skills / Cursor 文檔,可把該目錄放到工具會掃描的路徑,例如:

工具 常見目錄(項目級 / 用戶級)
Cursor .cursor/skills/~/.cursor/skills/(也兼容 .agents/skills/ 等)
Claude Code .claude/skills/~/.claude/skills/
Codex .agents/skills/ / .codex/skills/ 等(以當前 Codex 文檔爲準)

手動獲取示例:

git clone https://github.com/openai/skills.git
# 將 skills/.curated/security-ownership-map 複製到上述 skills 目錄之一
# 目錄名保持爲 security-ownership-map,內含 SKILL.md

啓用後,在 Agent 對話裏明確提出「做安全所有權 / Bus Factor 分析」即可;在 Cursor 中也可通過 /security-ownership-map 一類方式顯式調用(以當前客戶端能力爲準)。

典型用法

1. 生成所有權地圖

在倉庫根目錄執行官方 Quick start(路徑需按你本地 Skill 安裝位置調整):

python skills/skills/security-ownership-map/scripts/run_ownership_map.py \
  --repo . \
  --out ownership-map-out \
  --since "12 months ago" \
  --emit-commits

默認使用 author 身份與 author date,並排除 merge commit。如需改用 committer、或包含 merge,可加 --identity committer--date-field committer--include-merges

輸出目錄 ownership-map-out/ 中常見產物包括:

  • people.csv / files.csv / edges.csv:人、文件、觸摸邊
  • cochange_edges.csv:文件共變邊(可用 --no-cochange 關閉)
  • summary.json:安全所有權結論摘要
  • communities.jsoncochange.graph.json:社區與圖結構
  • commits.jsonl:加了 --emit-commits 時纔有
  • ownership.graphml / cochange.graphml:加了 --graphml 時纔有

people.csv 還會根據提交時區偏移給出 primary_tz_offsetprimary_tz_minutestimezone_offsets 等字段。

2. 自定義敏感路徑規則

默認會標記常見 auth / crypto / secret 路徑。若要覆蓋,可提供 CSV:

# pattern,tag,weight
**/auth/**,auth,1.0
**/crypto/**,crypto,1.0
**/*.pem,secrets,1.0

然後:

python .../run_ownership_map.py \
  --repo . \
  --out ownership-map-out \
  --sensitive-config path/to/sensitive.csv

3. 用查詢腳本取「有界」結果

構建完成後,用 query_ownership.py 按問題切片,例如:

# 孤兒敏感代碼(陳舊 + 低 Bus Factor)
python .../query_ownership.py --data-dir ownership-map-out summary --section orphaned_sensitive_code

# 隱性大戶(hidden owners)
python .../query_ownership.py --data-dir ownership-map-out summary --section hidden_owners

# 低 Bus Factor 的敏感熱點
python .../query_ownership.py --data-dir ownership-map-out summary --section bus_factor_hotspots

# auth / crypto 且 bus_factor <= 1
python .../query_ownership.py --data-dir ownership-map-out files --tag auth --bus-factor-max 1
python .../query_ownership.py --data-dir ownership-map-out files --tag crypto --bus-factor-max 1

# 誰最常碰敏感代碼
python .../query_ownership.py --data-dir ownership-map-out people --sort sensitive_touches --limit 10

summary.json 中相關結構大致如下(字段可按需要擴展):

{
  "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"
    }
  ]
}

官方還提供 community_maintainers.py,可按月/季查看某個文件所在社區的維護者變化。

4. 導入圖數據庫(可選)

需要把 CSV 落到 Neo4j 時,按 Skill 內 references/neo4j-import.md:把 people.csvfiles.csvedges.csv(以及需要的 cochange_edges.csv)放到 Neo4j import 目錄,建唯一約束後 LOAD CSV。Gephi 則可分別把人/文件當節點、邊文件當邊導入。可視化時可用 sensitivity_score > 0 過濾安全相關簇。

適用場景與注意事項

適合:

  • 企業安全 / AppSec 做「敏感路徑還有沒有人守」的盤點
  • 對照 CODEOWNERS,用提交現實覈對所有權漂移
  • 識別 Bus Factor 過低的 auth、crypto 等熱點
  • 需要導出 CSV/JSON,再進 Neo4j、Gephi 做覆盤或彙報

注意:

  • Skill 描述要求顯式安全所有權 / Bus Factor 意圖才觸發,避免當成通用 blame 工具。
  • git log 過大時用 --since / --until 收窄窗口;共變噪聲可用 --cochange-exclude--cochange-max-files 等參數壓制。
  • 觸摸計數默認按「一次作者提交」計,不是按文件逐次;需要按文件計可用 --touch-mode file。也可用 --window-days--weight recency 等平滑 churn。
  • 分析結果是歷史提交統計,不是權限系統真相;敏感路徑規則要按倉庫實際調整,並與 CODEOWNERS、值班表交叉驗證。
  • 上游 openai/skills 已標註廢棄,長期集成建議關注官方 Plugins 文檔與遷移說明,同時可把 Skill 目錄固定進自己的倉庫,避免依賴目錄倉庫生命週期。

小結

security-ownership-map 把 Git 歷史變成可查詢的安全責任拓撲:建圖、算 Bus Factor、標敏感孤兒與隱性大戶,再按需導出或導入圖庫。對企業安全團隊來說,它補的是「紙面歸屬」和「真實提交」之間的那一段空白。

官方地址:https://github.com/openai/skills/tree/main/skills/.curated/security-ownership-map

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜