前言¶
很多團隊都有 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、腳本與參考文檔。
核心功能與亮點¶
根據官方說明,主要能力包括:
- 人–文件二部圖:從 Git 歷史構建 people ↔ files 拓撲,刻畫「誰碰過哪些文件」。
- 敏感代碼與 Bus Factor:默認識別常見 auth / crypto / secrets 路徑,計算所有權風險;
summary.json中會給出bus_factor_hotspots、orphaned_sensitive_code、hidden_owners等安全向結論。 - 共變圖(co-change):按共享提交的 Jaccard 相似度聚類「經常一起改動」的文件;默認忽略 lockfile、
.github/*、編輯器配置等「膠水文件」,並默認排除 Dependabot 類提交,減少噪聲。 - 社區檢測:依賴
networkx,默認計算 community,併爲每個社區給出 maintainers。 - 可查詢、可導出:輸出 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.json、cochange.graph.json:社區與圖結構commits.jsonl:加了--emit-commits時纔有ownership.graphml/cochange.graphml:加了--graphml時纔有
people.csv 還會根據提交時區偏移給出 primary_tz_offset、primary_tz_minutes、timezone_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.csv、files.csv、edges.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