security-ownership-map

--- Analysez les dépôts git pour construire une topologie de propriété orientée sécurité (personnes-fichiers), calculez le facteur bus et la propriété du code sensible, et exportez en CSV/JSON pour les bases de données graphiques et la visualisation. Déclenchez uniquement lorsque l'utilisateur souhaite explicitement une analyse de propriété orientée sécurité ou une analyse du facteur bus fondée sur l'historique git (par exemple : code sensible orphelin, responsables sécurité, vérifications de réalité CODEOWNERS pour les risques, points chauds sensibles ou clusters de propriété). Ne déclenchez pas pour les listes générales de responsables ou les questions de propriété non liées à la sécurité.

npx skills add https://github.com/openai/skills --skill security-ownership-map

Carte de propriété de la sécurité

Aperçu

Construire un graphe bipartite de personnes et de fichiers à partir de l'historique git, puis calculer le risque de propriété et exporter les artefacts du graphe pour Neo4j/Gephi. Construire également un graphe de co-changement de fichiers (similarité de Jaccard sur les commits partagés) pour regrouper les fichiers selon la façon dont ils évoluent ensemble tout en ignorant les commits volumineux et bruyants.

Prérequis

  • Python 3
  • networkx (requis ; la détection de communautés est activée par défaut)

Installez avec :

pip install networkx

Flux de travail

  1. Définir la portée du dépôt et la fenêtre de temps (optionnel --since/--until).
  2. Décider des règles de sensibilité (utiliser les valeurs par défaut ou fournir une configuration CSV).
  3. Construire la carte de propriété avec scripts/run_ownership_map.py (le graphe de co-changement est activé par défaut ; utilisez --cochange-max-files pour ignorer les commits supernœud).
  4. Les communautés sont calculées par défaut ; la sortie graphml est optionnelle (--graphml).
  5. Interroger les résultats avec scripts/query_ownership.py pour les tranches JSON bornées.
  6. Persister et visualiser (voir references/neo4j-import.md).

Par défaut, le graphe de co-changement ignore les fichiers « glu » courants (lockfiles, .github/*, configuration d'éditeur) afin que les regroupements reflètent le mouvement réel du code au lieu des modifications d'infrastructure partagée. Remplacer avec --cochange-exclude ou --no-default-cochange-excludes. Les commits Dependabot sont exclus par défaut ; remplacer avec --no-default-author-excludes ou ajouter des modèles via --author-exclude-regex.

Si vous souhaitez exclure le glu de construction Linux comme Kbuild du regroupement de co-changement, passez :

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

Démarrage rapide

Exécutez à partir de la racine du dépôt :

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

Valeurs par défaut : identité de l'auteur, date de l'auteur et commits de fusion exclus. Utilisez --identity committer, --date-field committer, ou --include-merges si nécessaire.

Exemple (remplacer les exclusions de co-changement) :

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

Les communautés sont calculées par défaut. Pour désactiver :

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

Règles de sensibilité

Par défaut, le script signale les chemins d'authentification/crypto/secret courants. Remplacer en fournissant un fichier CSV :

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

Utilisez-le avec --sensitive-config path/to/sensitive.csv.

Artefacts de sortie

ownership-map-out/ contient :

  • people.csv (nœuds : personnes)
  • files.csv (nœuds : fichiers)
  • edges.csv (arêtes : touches)
  • cochange_edges.csv (arêtes de co-changement fichier-à-fichier avec poids de Jaccard ; omis avec --no-cochange)
  • summary.json (conclusions de propriété de sécurité)
  • commits.jsonl (optionnel, si --emit-commits)
  • communities.json (calculé par défaut à partir des arêtes de co-changement si disponibles ; inclut maintainers par communauté ; désactiver avec --no-communities)
  • cochange.graph.json (JSON de lien-nœud NetworkX avec community_id + community_maintainers ; revenir à ownership.graph.json si aucune arête de co-changement)
  • ownership.graphml / cochange.graphml (optionnel, si --graphml)

people.csv inclut la détection du fuseau horaire basée sur les décalages de commit de l'auteur : primary_tz_offset, primary_tz_minutes, et timezone_offsets.

Assistant de requête LLM

Utilisez scripts/query_ownership.py pour retourner de petites tranches JSON bornées sans charger le graphe complet en contexte.

Exemples :

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

Utilisez --community-top-owners 5 (par défaut) pour contrôler le nombre de mainteneurs stockés par communauté.

Requêtes de sécurité de base

Exécutez celles-ci pour répondre aux questions courantes de propriété de sécurité avec une sortie bornée :

# Code sensible orphelin (stale + bus factor faible)
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out summary --section orphaned_sensitive_code

# Propriétaires cachés pour les tags sensibles
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out summary --section hidden_owners

# Points chauds sensibles avec bus factor faible
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out summary --section bus_factor_hotspots

# Fichiers auth/crypto avec 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

# Qui touche le plus au code sensible
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out people --sort sensitive_touches --limit 10

# Voisins de co-changement (indices de regroupement pour déviation de propriété)
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

# Mainteneurs de communauté (pour un regroupement)
python skills/skills/security-ownership-map/scripts/query_ownership.py --data-dir ownership-map-out community --id 3

# Mainteneurs mensuels pour la communauté contenant un fichier
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

# Compartiments trimestriels au lieu de mensuels
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

Remarques :

  • Les touches consistent par défaut en un commit créé (non par fichier). Utilisez --touch-mode file pour compter les touches par fichier.
  • Utilisez --window-days 90 ou --weight recency --half-life-days 180 pour lisser l'agitation.
  • Filtrez les bots avec --ignore-author-regex '(bot|dependabot)'.
  • Utilisez --min-share 0.1 pour afficher uniquement les mainteneurs stables.
  • Utilisez --bucket quarter pour les regroupements de trimestres calendaires.
  • Utilisez --identity committer ou --date-field committer pour passer de l'attribution de l'auteur.
  • Utilisez --include-merges pour inclure les commits de fusion (exclus par défaut).

Format de résumé (par défaut)

Utilisez cette structure, ajoutez des champs si nécessaire :

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

Persistance du graphe

Utilisez references/neo4j-import.md lorsque vous devez charger les CSV dans Neo4j. Il comprend des contraintes, des Cypher d'importation et des conseils de visualisation.

Remarques

  • bus_factor_hotspots dans summary.json répertorie les fichiers sensibles avec bus factor faible ; orphaned_sensitive_code est le sous-ensemble stale.
  • Si git log est trop volumineux, réduisez avec --since ou --until.
  • Comparez summary.json par rapport à CODEOWNERS pour mettre en évidence la déviation de propriété.