数据分析

security-ownership-map

试用

从 Git 历史梳理安全代码归属,识别 Bus Factor 风险,并导出可用于图分析的 CSV/JSON 产物。

它能做什么

基于 Git 提交历史(默认按作者归属)构建人员与文件的二部归属图,识别敏感代码热点、孤立敏感代码和 Bus Factor 指标。文件共变更图按共享提交的 Jaccard 相似度进行聚类,默认排除常见胶水文件和 Dependabot 提交。结果可导出为 CSV、JSON、GraphML,以及面向 Neo4j/Gephi 的图产物,也可以用查询脚本获取有界 JSON 片段。

什么时候用它

  • 定位孤立且 Bus Factor 较低的敏感代码
  • 核查敏感文件的关键维护者分布
  • 比对 Git 归属与 CODEOWNERS 的偏差
  • 按文件共变更相似度发现所有权漂移聚类

技能文档

Security Ownership Map

Overview

Build a bipartite graph of people and files from git history, then compute ownership risk and export graph artifacts for Neo4j/Gephi. Also build a file co-change graph (Jaccard similarity on shared commits) to cluster files by how they move together while ignoring large, noisy commits.

Requirements

  • Python 3
  • networkx (required; community detection is enabled by default)

Install with:

pip install networkx

Workflow

  1. Scope the repo and time window (optional --since/--until).
  2. Decide sensitivity rules (use defaults or provide a CSV config).
  3. Build the ownership map with scripts/run_ownership_map.py (co-change graph is on by default; use --cochange-max-files to ignore supernode commits).
  4. Communities are computed by default; graphml output is optional (--graphml).
  5. Query the outputs with scripts/query_ownership.py for bounded JSON slices.
  6. Persist and visualize (see references/neo4j-import.md).

By default, the co-change graph ignores common “glue” files (lockfiles, .github/*, editor config) so clusters reflect actual code movement instead of shared infra edits. Override with --cochange-exclude or --no-default-cochange-excludes. Dependabot commits are excluded by default; override with --no-default-author-excludes or add patterns via --author-exclude-regex.

If you want to exclude Linux build glue like Kbuild from co-change clustering, pass:

python skills/skills/security-ownership-map/scripts/run_ownership_map.py \
  --repo /path/to/linux \
  --out ownership-map-out \
  --cochange-exclude "**/Kbuild"

Quick start

Run from the repo root:

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

Defaults: author identity, author date, and merge commits excluded. Use --identity committer, --date-field committer, or --include-merges if needed.

Example (override co-change excludes):

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

Communities are computed by default. To disable:

python skills/skills/security-ownership-map/scripts/run_ownership_map.py \
  --repo . \
  --out ownership-map-out \
  --no-communities

Sensitivity rules

By default, the script flags common auth/crypto/secret paths. Override by providing a CSV file:

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

Use it with --sensitive-config path/to/sensitive.csv.

Output artifacts

ownership-map-out/ contains:

  • people.csv (nodes: people)
  • files.csv (nodes: files)
  • edges.csv (edges: touches)
  • cochange_edges.csv (file-to-file co-change edges with Jaccard weight; omitted with --no-cochange)
  • summary.json (security ownership findings)
  • commits.jsonl (optional, if --emit-commits)
  • communities.json (computed by default from co-change edges when available; includes maintainers per community; disable with --no-communities)
  • cochange.graph.json (NetworkX node-link JSON with community_id + community_maintainers; falls back to ownership.graph.json if no co-change edges)
  • ownership.graphml / cochange.graphml (optional, if --graphml)

people.csv includes timezone detection based on author commit offsets: primary_tz_offset, primary_tz_minutes, and timezone_offsets.

LLM query helper

Use scripts/query_ownership.py to return small, JSON-bounded slices without loading the full graph into context.

Examples:

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

Use --community-top-owners 5 (default) to control how many maintainers are stored per community.

Basic security queries

Run these to answer common security ownership questions with bounded output:

# 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

Notes:

  • Touches default to one authored commit (not per-file). Use --touch-mode file to count per-file touches.
  • Use --window-days 90 or --weight recency --half-life-days 180 to smooth churn.
  • Filter bots with --ignore-author-regex '(bot|dependabot)'.
  • Use --min-share 0.1 to show stable maintainers only.
  • Use --bucket quarter for calendar quarter groupings.
  • Use --identity committer or --date-field committer to switch from author attribution.
  • Use --include-merges to include merge commits (excluded by default).

Summary format (default)

Use this structure, add fields if needed:

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

Graph persistence

Use references/neo4j-import.md when you need to load the CSVs into Neo4j. It includes constraints, import Cypher, and visualization tips.

Notes

  • bus_factor_hotspots in summary.json lists sensitive files with low bus factor; orphaned_sensitive_code is the stale subset.
  • If git log is too large, narrow with --since or --until.
  • Compare summary.json against CODEOWNERS to highlight ownership drift.

常见问题

它需要哪些输入和环境?
需要 Git 仓库、Python 3 和 `networkx` 包。可以用可选的 `--since`、`--until` 参数限定时间范围,也支持通过 CSV 配置敏感路径规则。
可以导出哪些结果?
可以生成人员、文件、边和共变更关系的 CSV,以及安全归属 `summary.json`、可选的提交记录、Community 数据、NetworkX 点边 JSON 和可选的 GraphML 文件。查询脚本还能返回小而有界的 JSON 片段,避免把完整图加载到上下文中。
如何降低共变更聚类中的噪声?
共变更聚类默认排除常见胶水文件和 Dependabot 提交。可以用 `--cochange-exclude` 增加排除规则,用 `--no-default-author-excludes` 关闭默认作者排除,或用 `--author-exclude-regex` 添加作者模式。

相关技能

从 AdMapix API 拉取广告创意、应用、榜单和收入预估等数据,原样返回结构化 JSON。

作者 fly0pants4.3k 次安装296 星标

把自然语言描述转为结构化 JSON,并由 mcp-diagram-generator MCP 服务生成 Draw.io、Mermaid 或 Excalidraw 图表文件。

作者 nssa.io1.0k 次安装47 星标

通过托管 OAuth 代理网关对接 Airtable,对 Base、表和记录执行增删改查。

298 次安装15 星标

通过 Maton 托管的 OAuth 代理读写 Zoho CRM 记录,所有写入操作均需用户确认。

463 次安装6 星标

通过托管 OAuth 代理连接 Notion 工作区,支持搜索、数据库查询与读取,写入需用户确认。

340 次安装8 星标

通过托管 OAuth 读写 Zoho Recruit 的候选人、职位和面试数据。

487 次安装3 星标

OpenAI 的更多技能

浏览全部技能

以文档为先,为 ChatGPT Apps SDK 应用生成 MCP 服务端与组件脚手架。

作者 OpenAI26.4k 星标

把代码或文字描述里的整页转成 Figma 屏幕,并保持引用已发布设计系统的组件、变量和样式。

作者 OpenAI26.4k 星标

按五阶段流程与强制检查点,搭建与代码对齐的 Figma 设计系统。

作者 OpenAI26.4k 星标

figma-use

官方

在任何 use_figma 调用前强制加载,约束 Plugin API 脚本关键规则,避免常见脚本错误。

作者 OpenAI26.4k 星标

imagegen

官方

在项目流程中直接生成或编辑位图,默认走内置工具路径。

作者 OpenAI26.4k 星标

从 OpenAI 官方开发者文档中获取带引用的最新答案,用于基于 OpenAI 产品和 API 的开发。

作者 OpenAI26.4k 星标