Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
gh-safe-repo — CLI Python qui crée des dépôts GitHub avec des paramètres par défaut sécurisés — protection des branches, Dependabot, scanning des secrets et analyse de sécurité préalable — appliqués automatiquement. | Kitploit
Outils/GitHubGitHub/ariesq/gh-safe-repo
Utilitaires GénérauxScanners de VulnérabilitésScripting et AutomatisationAudit de ConfigurationSécurité CloudDevSecOpsDétection de Secrets
GitHubariesq/gh-safe-repo

gh-safe-repo

CLI Python qui crée des dépôts GitHub avec des paramètres par défaut sécurisés — protection des branches, Dependabot, scanning des secrets et analyse de sécurité préalable — appliqués automatiquement.

Voir le dépôt
383il y a 17h 13mVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

gh-safe-repo

Créez des dépôts GitHub avec des paramètres par défaut sécurisés appliqués automatiquement. Remplace la liste de vérification des paramètres post-création de cinq minutes par une seule commande.``` gh-safe-repo create <owner/repo>

root@kitploit:~
Protection de branche, tags immuables, Dependabot, permissions Actions restreintes, analyse des secrets avec protection push, ainsi que wiki et projets désactivés — le tout configuré avant même d'écrire votre première ligne de code.

gh-safe-repo est en cours de développement intensif. Il fonctionne bien pour le cas d'usage de création d'un nouveau dépôt avec des paramètres sécurisés par défaut. Je travaille à peaufiner les options CLI pour qu'elles correspondent au mieux aux attentes des utilisateurs. Attendez-vous à des changements potentiellement cassants jusqu'à ce que j'atteigne un stade où je publie des versions et que l'intégration continue / déploiement continu soit bien rodée. ✌️

---

## Table des matières

- [Pourquoi](#why)
- [Ce qu'il modifie](#what-it-changes)
- [Prérequis](#requirements)
- [Installation](#installation)
- [Démarrage rapide](#quick-start)
- [Référence CLI](#cli-reference)
- [Sortie du mode planification / Dry Run](#dry-run--plan-output)
- [Mode Correction (Auditer les dépôts existants)](#fix-mode-audit-existing-repos)
- [Miroir de dépôts (`--from`)](#mirroring-repos---from)
- [Créer un dépôt à partir d'un répertoire local (`--local`)](#creating-a-repo-from-a-local-directory---local)
- [Analyseur de sécurité préalable](#pre-flight-security-scanner)
  - [Analyse autonome](#standalone-scan)
  - [Suppression des faux positifs](#suppressing-false-positives)
- [Configuration](#configuration)
- [Limitations des plans GitHub](#github-plan-limitations)
- [Comment ça fonctionne](#how-it-works)
- [Développement](#development)

---

## Pourquoi

Les paramètres par défaut des dépôts GitHub sont optimisés pour la découvrabilité et la flexibilité, pas pour la sécurité. Chaque nouveau dépôt est livré avec :

- Wiki et Projets activés (surface d'attaque, même inutilisés)
- Fusion par commit autorisée (historique désordonné, mais ce n'est pas le principal problème)
- Aucune protection de branche (toute personne ayant un accès en écriture peut pousser directement sur `main`)
- Aucune alerte Dependabot
- GitHub Actions avec des permissions d'écriture sur le dépôt
- Actions autorisées à approuver les pull requests

Corriger tout cela manuellement prend plusieurs minutes par dépôt et est facile à oublier. `gh-safe-repo` applique un ensemble de paramètres par défaut pragmatiques mais sécurisés en une seule fois, avec un aperçu du plan afin que vous sachiez exactement ce qui va changer avant que quoi que ce soit ne se produise.

---

## Ce qu'il modifie

### Paramètres du dépôt

| Paramètre | Par défaut GitHub | Par défaut sécurisé | Remarques |
|---|---|---|---|
| Visibilité | Public | **Privé** | Passez `--public` pour modifier |
| Wiki | Activé | **Désactivé** | |
| Projets | Activé | **Désactivé** | |
| Issues | Activé | Activé | |
| Supprimer la branche lors de la fusion | Désactivé | Désactivé | Mettez à `true` dans la configuration pour le nettoyage automatique |
| Autoriser les fusions par commit | Activé | Activé | Mettez à `false` dans la configuration pour les fusions par squash uniquement |
| Autoriser la fusion par squash | Activé | Activé | |
| Autoriser la fusion par rebase | Activé | Activé | |

### GitHub Actions

| Paramètre | Par défaut GitHub | Par défaut sécurisé |
|---|---|---|
| Actions autorisées | Toutes | **Sélectionnées** (appartenant à GitHub + créateurs vérifiés ; personnalisable) |
| Permissions de workflow par défaut | Lecture/écriture | **Lecture seule** |
| Les Actions peuvent approuver les PR | Oui | **Non** |
| Exiger l'épinglage SHA | Non | **Oui** (les workflows doivent épingler les actions à un SHA de commit, pas à un tag mutable) |
| Politique d'approbation des PR de fork | Contributeurs novices nouveaux sur GitHub | **Tous les contributeurs externes** — exiger une approbation avant que les workflows PR de fork n'exécutent le CI. Options : uniquement les nouveaux comptes GitHub (par défaut GitHub), les contributeurs novices du dépôt, ou toutes les PR de fork (le plus sûr) |

### Protection de branche (dépôts publics, ou tout dépôt sur un plan payant)

| Règle | Valeur |
|---|---|
| Exiger une pull request avant fusion | Oui |
| Nombre de critiques approuvées requis | 1 |
| Ignorer les critiques obsolètes lors du push | Oui |
| Exiger la résolution des conversations | Oui |
| Autoriser les pushes forcés | Non |
| Autoriser la suppression de branche | Non |
| Appliquer aux administrateurs | Non (permet aux outils du propriétaire de pousser) |

La protection de branche est appliquée via **l'API Rulesets** par défaut (`use_rulesets = true`) : un seul ruleset `gh-safe-repo defaults` couvre chaque branche configurée et exprime « les administrateurs peuvent contourner » via un acteur de contournement plutôt que par le drapeau classique `enforce_admins`. Définissez `use_rulesets = false` pour le chemin classique par branche hérité (conservé pour un cycle de publication).

**Migration d'un dépôt existant depuis la protection classique :** si `fix` trouve une protection de branche classique sur un dépôt, il refuse de la convertir en ruleset sauf si vous passez `--migrate-branch-protection`. Les règles exclusives classiques n'ont pas d'équivalent dans le ruleset que cet outil construit et seraient abandonnées silencieusement autrement — lacunes connues :

- `required_status_checks` — les vérifications CI requises ne sont pas modélisées dans le corps du ruleset.
- `restrictions` (restrictions de push par utilisateur/équipe) — Rulesets modélise cela différemment via des acteurs de contournement ; ce n'est pas une correspondance 1:1.
- Divergence par branche — un ruleset à condition unique partagée ne peut pas exprimer des règles différentes pour `master` vs `main`.

Avec le drapeau, `fix` crée/met à jour le ruleset puis supprime la protection classique sur chaque branche pour que les deux couches ne s'empilent pas.

### Protection des tags (dépôts publics, ou tout dépôt sur un plan payant)

La protection des tags crée un GitHub Ruleset ciblant tous les tags (`*` par défaut, configurable via `protected_tags`). Les règles suivantes sont appliquées :

| Règle du ruleset | Appliquée ? | Remarques |
|---|---|---|
| Restreindre les créations | Non | |
| **Restreindre les mises à jour** | **Oui** | Empêche la réécriture / le push forcé des tags |
| **Restreindre les suppressions** | **Oui** | Empêche `git push --delete` des tags |
| Exiger un historique linéaire | Non | |
| Exiger le succès des déploiements | Non | |
| Exiger des commits signés | Non | |
| Exiger la réussite des vérifications de statut | Non | |
| Bloquer les pushes forcés | Non | |

Les administrateurs du dépôt sont dans la liste de contournement (conformément au défaut `enforce_admins = false` de la protection de branche). Fonctionne uniquement sur les dépôts publics ou les plans GitHub payants (même restriction que la protection de branche). Les dépôts privés en plan gratuit verront cette étape ignorée dans la sortie du plan.

### Sécurité

| Fonctionnalité | Comportement |
|---|---|
| Alertes Dependabot | Activé (dépôts publics / plans payants) |
| Mises à jour de sécurité Dependabot | Activé (ouvre automatiquement des PR pour les dépendances vulnérables) |
| Analyse des secrets | Automatique sur les dépôts publics ; activé sur les plans privés payants |
| Protection push | Activé (bloque les commits contenant des secrets pris en charge) |
| Signalement privé de vulnérabilités | Activé (permet aux chercheurs de sécurité de signaler en privé) |
| Graphique des dépendances | Automatique sur les dépôts publics ; pas d'API REST pour les dépôts privés (interface uniquement) |

---

## Prérequis

- Python 3.8+
- [`gh` CLI](https://cli.github.com/) installé et authentifié (`gh auth login`), **ou** `GITHUB_TOKEN` défini dans votre environnement
- Pour `--local` / `--from` (qui poussent ou clonent du code) : vos identifiants git habituels doivent être configurés — soit une clé SSH chargée dans `ssh-agent` (lorsque `gh config get git_protocol` est `ssh`) soit un helper d'identification HTTPS (`gh auth setup-git` en configure un automatiquement). Le jeton OAuth **n'est pas** utilisé pour git push, donc les fichiers de workflow (`.github/workflows/*`) se poussent sans nécessiter la portée OAuth `workflow`.
- [`uv`](https://docs.astral.sh/uv/) pour l'installation à partir des sources (recommandé)
- `truffleHog` v3 (optionnel — utilisé par l'analyseur préalable ; détecté automatiquement dans le PATH, ou exécuté via podman/docker ; se rabat sur les expressions régulières si aucun n'est disponible)

---

## Installation

### À partir des sources avec uv (recommandé)```bash
git clone https://github.com/your-username/gh-safe-repo
cd gh-safe-repo
uv tool install .

Cela installe gh-safe-repo dans l'environnement d'outils d'uv et l'ajoute à votre PATH.

Exécuter directement sans installation```bash

git clone https://github.com/your-username/gh-safe-repo cd gh-safe-repo uv sync # creates .venv ./gh-safe-repo create <owner/repo>

root@kitploit:~
### Vérification```bash
gh-safe-repo --help

Démarrage rapide```bash

Create a private repo with all safe defaults

gh-safe-repo create <owner/repo>

Preview what would happen — no changes made

gh-safe-repo create <owner/repo> --dry-run

Create a public repo (branch protection + security scanning applied)

gh-safe-repo create <owner/repo> --public

Mirror an existing repo into a new private repo (with pre-flight scan)

gh-safe-repo create <owner/repo> --from <owner/source>

Mirror a private repo to a new public repo (with pre-flight scan)

gh-safe-repo create <owner/pub> --from <owner/priv> --public

Create a repo from a local directory (with pre-flight scan)

gh-safe-repo create <owner/repo> --local ~/projects/myapp

Same, but make it public (branch protection applied before push)

gh-safe-repo create <owner/repo> --local ~/projects/myapp --public

Audit an existing repo and apply any missing safe defaults

gh-safe-repo fix <owner/repo>

Audit without making changes

gh-safe-repo fix <owner/repo> --dry-run

Apply fixes without confirmation prompt (scripting/batch use)

gh-safe-repo fix <owner/repo> --yes

Scan a local repo for secrets before pushing anywhere

gh-safe-repo scan . gh-safe-repo scan ~/projects/myapp

root@kitploit:~
## Référence CLI```
gh-safe-repo create <owner/repo> [OPTIONS]
gh-safe-repo fix <owner/repo> [OPTIONS]
gh-safe-repo scan <path> [OPTIONS]

Toutes les commandes qui interagissent avec GitHub nécessitent le format owner/repo (par exemple myuser/my-repo). Pour create, le propriétaire est validé par rapport à votre compte GitHub authentifié pour éviter les erreurs sur les systèmes multi-comptes. Pour fix, des permissions d'administration sur le dépôt cible sont requises à la place, ce qui vous permet de corriger les dépôts appartenant à des organisations ou à d'autres comptes où vous avez un accès administrateur.

create — Créer un nouveau dépôt

Un create simple (sans --local/--from) initialise le dépôt pour qu'une branche par défaut existe pour la protection de branche, puis supprime le README.md généré automatiquement afin que le nouveau dépôt démarre proprement. Définissez auto_init = true dans la configuration pour conserver le README à la place. --local/--from poussent votre propre historique et ne créent jamais de README.

fix — Auditer et corriger un dépôt existant

scan — Analyse locale des secrets

OptionDescription
--config [PATH]Chemin vers le fichier de configuration ; --config seul utilise uniquement les valeurs par défaut intégrées
--debugAfficher les détails du scanner

Le code de sortie est 0 si aucun résultat critique, 1 si des résultats critiques sont trouvés.


Sortie de simulation / Plan

--dry-run montre exactement ce que ferait gh-safe-repo, sans apporter de modifications ni faire d'appels API. Utilisez-le avant de lancer pour de vrai. Combinez avec --json pour une sortie de plan lisible par machine :```bash gh-safe-repo create <owner/repo> --dry-run --json gh-safe-repo fix <owner/repo> --dry-run --json

root@kitploit:~
Lorsque `--json` est actif, le plan est écrit sur stdout sous forme d'objet JSON et tous les autres messages (progression, avertissements, le pied de page "Dry run") vont sur stderr, de sorte que la sortie soit propre pour le piping ou le scripting.```
$ gh-safe-repo create <owner/repo> --dry-run

  Plan for my-project (private)

  Category            Action  Setting                          Value
  ──────────────────────────────────────────────────────────────────
  Repository          ADD     repository                       my-project (private)
  Repository          ADD     has_wiki                         false
  Repository          ADD     has_projects                     false
  Actions             ADD     default_workflow_permissions     read
  Actions             ADD     can_approve_pull_request_reviews false
  Branch Protection   SKIP    branch_protection                Not available for private repos on free plan
  Security            SKIP    dependabot_alerts                Not available for private repos on free plan
  1 setting skipped (GitHub plan limitation).
  Dry run — no changes made.

Couleurs des actions :

Sortie JSON (--json):```json { "changes": [ { "type": "add", "category": "repository", "key": "has_wiki", "old": null, "new": false, "reason": null }, { "type": "skip", "category": "branch_protection", "key": "branch_protection", "old": null, "new": null, "reason": "Not available for private repos on free plan" } ], "summary": { "add": 5, "skip": 2 } }

root@kitploit:~
`summary` n'inclut que les types présents dans le plan. Les consommateurs devraient utiliser `.get("delete", 0)` etc. plutôt que de supposer que les quatre clés sont présentes.

---

## Mode Correctif (Audit des Dépôts Existants)

`fix` compare les paramètres actuels d'un dépôt existant avec les valeurs par défaut sûres et applique les corrections nécessaires. Aucun scan de secrets — `fix` concerne uniquement les paramètres du dépôt.```bash
# See what's out of compliance
gh-safe-repo fix <owner/repo> --dry-run

# Apply missing safe defaults
gh-safe-repo fix <owner/repo>

# Apply without confirmation prompt (scripting/batch use)
gh-safe-repo fix <owner/repo> --yes

Mode de correction :

  1. Récupère la valeur actuelle de chaque paramètre via l’API GitHub
  2. Compare avec les paramètres sécurisés par défaut souhaités
  3. Affiche un tableau de plan avec UPDATE pour les réglages modifiés et SKIP pour les réglages déjà à la valeur souhaitée (détection d’opération nulle — il ne fait jamais d’appels API qui ne changeraient rien)
  4. Demande confirmation avant d’appliquer (ignorer avec --yes)

Seuls les changements réels sont appliqués — les réglages déjà à la valeur souhaitée sont affichés comme SKIP et ne génèrent aucun appel API.


Miroir de dépôts (--from)

--from crée un miroir d’un dépôt existant dans un nouveau dépôt avec des paramètres par défaut sécurisés. Cela fonctionne aussi bien pour les destinations privées que publiques :```bash

Mirror into a new private repo (default)

gh-safe-repo create <owner/repo> --from <owner/source>

Mirror a private repo to a new public repo (riskiest operation — scanned thoroughly)

gh-safe-repo create <owner/pub> --from <owner/priv> --public

root@kitploit:~
**Ce qui se passe, dans l'ordre :**

1. Vos identifiants git pour `github.com` sont vérifiés en amont (sonde SSH lorsque `gh config get git_protocol` est `ssh` ; HTTPS est considéré comme sûr), donc une clé manquante échoue rapidement avant la création de tout dépôt
2. Le dépôt source est cloné localement (clone complet, sans `--depth`, afin que truffleHog puisse parcourir l'historique complet des commits)
3. Le [scanner de sécurité pré-vol](#pre-flight-security-scanner) s'exécute sur le clone local
4. Vous examinez les résultats et confirmez (ou annulez)
5. Un nouveau dépôt est créé (privé par défaut, ou public avec `--public`)
6. Les permissions Actions et les paramètres de sécurité sont appliqués (Dependabot, analyse des secrets, protection de push)
7. L'historique complet est reflété : `git clone --mirror` + `git push --mirror`
8. La protection des branches et des tags est appliquée (après le push du code, afin que la branche cible existe)

Si l'analyse révèle un problème et que vous annulez, aucun code n'est jamais copié sur GitHub.

> **Note :** `--from` utilise le format `owner/repo` pour la source et la destination.

---

## Créer un dépôt à partir d'un répertoire local (`--local`)

`--local PATH` est l'équivalent local-à-GitHub de `--from`. Il crée un nouveau dépôt GitHub et envoie le code depuis un dépôt git local. `PATH` doit être un dépôt git initialisé (`git init` ou un clone).```bash
gh-safe-repo create <owner/repo> --local ~/projects/myapp
gh-safe-repo create <owner/repo> --local ~/projects/myapp --public

Ce qui se passe, dans l'ordre :

  1. Vos identifiants git pour github.com sont vérifiés en amont (sonde SSH lorsque gh config get git_protocol est ssh ; HTTPS est fiable), donc une clé manquante échoue rapidement avant que tout dépôt ne soit créé
  2. Le scanner de sécurité pré-vol s'exécute directement sur le répertoire local (pas besoin de clone)
  3. Vous examinez les résultats et confirmez (ou annulez)
  4. Un nouveau dépôt est créé, et les permissions des actions et les paramètres de sécurité sont appliqués
  5. L'historique complet est poussé avec push --all --tags (toutes les branches et tous les tags)
  6. La protection des branches et des tags est appliquée (après le push du code, pour que la branche cible existe)
  7. origin est ajouté au dépôt local original pointant vers la nouvelle URL GitHub, et le suivi amont de la branche courante est configuré — donc git push et git pull fonctionnent immédiatement sans configuration supplémentaire.

Les deux --local et --from fonctionnent pour les dépôts privés et publics. Ils sont mutuellement exclusifs.

La branche par défaut locale (via git -C PATH symbolic-ref HEAD) est utilisée pour cibler les règles de protection de branche, donc la protection atterrit sur la bonne branche même si ce n'est pas main.

Astuce : Exécutez gh-safe-repo scan PATH d'abord si vous voulez inspecter les résultats sans rien créer.


Scanner de sécurité pré-vol

Le scanner s'exécute localement et n'envoie jamais de code à GitHub. Utilisez-le de manière autonome avant tout push, ou il s'exécute automatiquement dans le cadre des workflows --from et --local.

Scan autonome```bash

Scan the current directory

gh-safe-repo scan .

Scan an explicit path

gh-safe-repo scan ~/projects/myapp

root@kitploit:~
Le code de sortie est `0` si aucun résultat critique n'est trouvé, `1` si des résultats critiques sont trouvés — ce qui permet de l'utiliser proprement avec d'autres commandes :```bash
gh-safe-repo scan . && git push

La configuration complète [pre_flight_scan] s'applique : banned_strings, max_file_size_mb, trufflehog_mode, etc.

Ce qu'il détecte

Moteur de scan

gh-safe-repo choisit automatiquement le meilleur scanner disponible en utilisant une chaîne de découverte en trois étapes :

  1. truffleHog v3 dans le PATH — exécute trufflehog --version, vérifie qu'il s'agit de la v3, et l'utilise. Une installation v2 ou une version non reconnue affiche un avertissement et passe à l'étape 2.
  2. podman ou docker — si aucun truffleHog natif n'est trouvé, le scanner exécute truffleHog dans un conteneur (ghcr.io/trufflesecurity/trufflehog:latest) en utilisant podman run ou docker run, en montant le chemin de scan en lecture seule au même chemin absolu afin que les chemins de sortie JSON soient identiques à une exécution native.
  3. Repli regex — si ni une installation native ni un environnement d'exécution de conteneur n'est disponible, un avertissement est affiché et le scanner regex s'exécute à la place. Il s'exécute également toujours en complément de truffleHog pour les e-mails et les TODO, et détecte les motifs d'ID de clé isolés que truffleHog ignore délibérément (truffleHog nécessite les deux moitiés d'une paire d'identifiants, par ex. AWS Key ID et Secret Access Key, avant de signaler une découverte).

Le scanner sélectionné est affiché dans l'en-tête "Running pre-flight security scan..." et dans l'entrée SCAN du tableau du plan, par ex. :``` Running pre-flight security scan... (truffleHog v3.93.4) Running pre-flight security scan... (truffleHog via podman) Running pre-flight security scan... (regex only — see warning above)

root@kitploit:~
Variables d'environnement respectées par le chemin du conteneur : `CONTAINER_RUNTIME` pour remplacer la sélection du runtime (par exemple `CONTAINER_RUNTIME=docker`), et `TRUFFLEHOG_IMAGE` pour épingler une étiquette d'image spécifique.

### Exécution de truffleHog via podman ou Docker (sans installation locale)

Aucune configuration manuelle n'est nécessaire. `gh-safe-repo` détecte automatiquement podman ou docker (étape 2 ci-dessus) et exécute truffleHog dans un conteneur avec les bons montages de volume. Les variables d'environnement `CONTAINER_RUNTIME` et `TRUFFLEHOG_IMAGE` sont respectées.

Un wrapper shell (`tools/trufflehog`) et un `Containerfile` pour construire une image locale épinglée sont fournis dans [`tools/`](https://github.com/ariesq/gh-safe-repo/blob/HEAD/tools/README.md) pour les utilisateurs qui souhaitent disposer de truffleHog basé sur un conteneur à l'échelle du système, ou qui ont besoin d'une image isolée (air-gapped).

### Révision interactive```
Pre-flight scan: my-private-project

  CRITICAL  my_private_project/config.py:12  AWS Access Key ID
            [redacted]

  WARNING   my_private_project/setup.py:3    Email address
            author_email="[email protected]"

  1 critical finding, 1 warning.

  Critical findings detected. Continue anyway? [y/N]:
  • Découvertes critiques : Par défaut, abandon (N). Vous devez taper explicitement y pour continuer.
  • Avertissements uniquement : Par défaut, continuer (Y). Appuyez sur Entrée pour continuer ou tapez n pour abandonner.
  • Aucune découverte : L'analyse se termine silencieusement et le workflow continue.

Les secrets sont masqués dans la sortie. Les adresses e-mail et les TODOs affichent la ligne correspondante.

Couverture d'analyse

Les répertoires d'artefacts de build (node_modules, __pycache__, .venv, venv, dist, build) sont ignorés par défaut pour maintenir la rapidité des analyses. Dans les dépôts git, cette exclusion est conditionnelle : avant de supprimer un répertoire, le scanner exécute git ls-files -- <dir> pour vérifier si des fichiers à l'intérieur sont suivis. Si c'est le cas, le répertoire est analysé normalement.

Cela signifie que les arborescences node_modules ou dist validées — inhabituelles, mais cela arrive — ne sont pas silencieusement ignorées. Les répertoires non validés (le cas normal) continuent d'être ignorés comme avant.

Un avertissement est toujours affiché lorsque des sous-répertoires SKIP_DIRS sont trouvés dans un dépôt source cloné, car leur présence peut indiquer que plus de contenu que prévu est validé.

Suppression des faux positifs

Deux clés de configuration vous permettent de supprimer les découvertes connues comme sûres sans désactiver des catégories entières de vérification.

scan_exclude_paths — ignorer complètement des fichiers ou répertoires. Les valeurs sont des motifs regex séparés par des sauts de ligne ou des virgules, mis en correspondance avec le chemin relatif du fichier. Un fichier correspondant est exclu de toutes les vérifications : secrets, e-mails, TODOs, gros fichiers et détection des fichiers de contexte IA. Les mêmes motifs sont également transmis à truffleHog via --exclude-paths, afin que la couverture soit cohérente quel que soit le moteur d'analyse actif.```ini [pre_flight_scan]

Exclude the GitHub API spec (example tokens) and all test fixtures

scan_exclude_paths = docs/api.github.com.json tests/fixtures/

root@kitploit:~
**`exclude_emails`** — supprimer les résultats d'emails pour des adresses spécifiques ou des domaines entiers. Les valeurs sont séparées par des sauts de ligne ou des virgules, insensibles à la casse. Les entrées commençant par `@` correspondent à tous les emails de ce domaine ; sinon, l'entrée doit correspondre exactement à l'adresse complète. S'applique à la fois aux résultats de l'arbre de travail et de l'historique git.```ini
[pre_flight_scan]
# Suppress bot addresses and placeholder domains
exclude_emails = [email protected], [email protected], @example.com

Configuration du scanner```ini

[pre_flight_scan] scan_for_secrets = true scan_for_emails = true scan_for_todos = true max_file_size_mb = 100

Scan git history for email addresses (requires scan_for_emails = true)

scan_email_history = true

Scanner selection: auto | native | docker | off

auto — try native truffleHog, fall back to container (podman/docker), then regex (default)

native — native truffleHog only; no container fallback

docker — container only; skip native PATH check

off — regex scanner only, no truffleHog attempt

trufflehog_mode = auto

Flag AI context files (CLAUDE.md, AGENTS.md, .cursorrules, etc.) as critical findings.

Their git history may contain more sensitive content than the current version.

warn_ai_context_files = true

Literal strings to flag as critical findings (case-insensitive).

Comma-separated or one per line (continuation lines must be indented).

banned_strings = secret

password

credential

Exclude files/directories from all scan checks (regex patterns, comma/newline separated).

The same patterns are passed to truffleHog via --exclude-paths.

scan_exclude_paths = docs/api.github.com.json

tests/fixtures/

Suppress email findings for specific addresses or entire domains (case-insensitive).

Entries starting with @ match all emails at that domain; otherwise exact address match.

exclude_emails = [email protected], [email protected], @example.com

root@kitploit:~
Lorsque des chaînes interdites ou des fichiers de contexte IA sont trouvés, le scanner imprime une commande `git filter-repo` prête à être exécutée pour les supprimer de l'historique du dépôt source avant de le relancer.

---

## Configuration

`gh-safe-repo` recherche la configuration dans cet ordre (la première correspondance l'emporte) :

1. **`--config PATH`** — remplacement explicite
2. **`./gh-safe-repo.ini`** — répertoire de travail actuel
3. **`$XDG_CONFIG_HOME/gh-safe-repo/gh-safe-repo.ini`** — par défaut `~/.config` lorsque `$XDG_CONFIG_HOME` n'est pas défini

`--config` seul (sans chemin) ignore complètement la recherche de fichier et utilise uniquement les valeurs par défaut intégrées.
Toutes les valeurs ont des valeurs par défaut sûres — aucun fichier de configuration n'est requis pour commencer.

Un exemple de configuration entièrement annoté est inclus dans le dépôt sous le nom `gh-safe-repo.ini.example`. Copiez-le pour commencer :```bash
# User-level config (XDG)
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/gh-safe-repo"
cp gh-safe-repo.ini.example "${XDG_CONFIG_HOME:-$HOME/.config}/gh-safe-repo/gh-safe-repo.ini"

# Or project-level config (current directory)
cp gh-safe-repo.ini.example ./gh-safe-repo.ini

Référence complète de la configuration```ini

[repo]

Whether new repos are private by default

private = true

Disable features that create clutter if unused

has_wiki = false has_projects = false has_issues = true

Auto-delete head branches after merge (default: off, matching GitHub)

delete_branch_on_merge = false

Merge strategies (all enabled by default, matching GitHub)

Set allow_merge_commit = false for squash-only workflows

allow_squash_merge = true allow_merge_commit = true allow_rebase_merge = true

Whether a plain create leaves an initialized README in the new repo.

false (default): the repo still gets a default branch (needed for branch

protection), but the auto-generated README.md is removed afterward.

true: keep the initialized README.

(Ignored for --local/--from, which always push your own history instead.)

auto_init = false

[actions]

Which actions are allowed to run: all | local_only | selected

allowed_actions = selected

When allowed_actions = selected, control which external actions are permitted:

github_owned_allowed = true # actions maintained by GitHub (e.g. actions/checkout) verified_allowed = true # actions from Marketplace verified creators

patterns_allowed = myorg/* # comma-separated allowlist (wildcards OK)

Principle of least privilege: read-only by default

Options: read | write

default_workflow_permissions = read

Prevent Actions from self-approving pull requests

can_approve_pull_request_reviews = false

Require workflows to pin actions to a specific commit SHA instead of a mutable tag

sha_pinning_required = true

[branch_protection]

Applied to public repos on any plan, and private repos on paid plans.

Branch to protect

protected_branch = main

Require a pull request before merging

require_pull_request = true

Number of approvals required

required_approving_reviews = 1

Dismiss existing approvals when new commits are pushed

dismiss_stale_reviews = true

Require all review comments to be resolved before merging

require_conversation_resolution = true

Do not enforce rules on administrators

false = repo owner can still push directly (needed for --from mirror workflow)

enforce_admins = false

Block force-pushes

allow_force_pushes = false

Block branch deletion

allow_deletions = false

Use the Rulesets API (default) instead of the legacy classic branch-protection

path. A single ruleset covers all configured branches, supports bypass actors,

and is GitHub's forward direction (new rule types are Rulesets-only). Set false

to fall back to the classic per-branch API, which is kept for one release cycle.

use_rulesets = true

[tag_protection]

Immutable tags via Rulesets API.

Only works on public repos or paid GitHub plans (same restriction as branch protection).

Glob pattern(s) for tags to protect — comma-separated.

protected_tags = *

Prevent deletion of matching tags (git tag -d / git push --delete)

prevent_tag_deletion = true

Prevent rewriting matching tags (git tag -f / force-push)

prevent_tag_update = true

[security]

Enable Dependabot vulnerability alerts

enable_dependabot_alerts = true

Auto-open PRs to fix vulnerable dependencies

enable_dependabot_security_updates = true

Let security researchers report vulnerabilities privately

enable_private_vulnerability_reporting = true

Block commits that contain supported secrets

enable_secret_scanning_push_protection = true

Note: The following features have no REST API and must be configured via UI or dependabot.yml:

- Grouped security updates: use dependabot.yml groups with applies-to: security-updates

- Automatic dependency submission: enable via repository settings UI

- Dependency graph: automatic for public repos; enable via UI for private repos

[pre_flight_scan] scan_for_secrets = true scan_for_emails = true scan_for_todos = true

Flag files larger than this threshold

max_file_size_mb = 100

Scan git history for email addresses (requires scan_for_emails = true)

scan_email_history = true

Scanner selection: auto | native | docker | off

auto = try native truffleHog, fall back to container (podman/docker), then regex

native = native PATH only

docker = container only

off = regex only

trufflehog_mode = auto

Flag AI context files (CLAUDE.md, AGENTS.md, .cursorrules, etc.) as critical findings.

warn_ai_context_files = true

Literal strings to flag as critical findings (case-insensitive).

Comma-separated, or one per line with continuation indentation.

banned_strings = secret

password

credential

Exclude files/directories from all scan checks (regex patterns, comma/newline separated).

Passed to truffleHog via --exclude-paths as well as applied to the regex walk.

scan_exclude_paths = docs/api.github.com.json

tests/fixtures/

Suppress email findings for specific addresses or entire domains (case-insensitive).

Entries starting with @ match all emails at that domain; otherwise exact address match.

exclude_emails = [email protected], [email protected], @example.com

[git_transport]

How git push/clone authenticates when using --local or --from: auto | user_creds | token

auto — use your own git credentials (SSH key or credential helper) when a

path exists; fall back to pushing over HTTPS with the API token in

the URL only when there is no SSH setup and no credential helper

(e.g. CI with just GITHUB_TOKEN). (default)

user_creds — never use the API token for git. Pushes with your own credentials

only; this avoids needing the workflow token scope to push

.github/workflows files.

token — always push over HTTPS with the API token in the URL. For CI where

the token was granted the workflow scope intentionally.

mode = auto

root@kitploit:~
---

## Limitations du plan GitHub

Certaines fonctionnalités ne sont disponibles qu'en fonction de la visibilité du dépôt et de votre plan GitHub.

| Fonctionnalité | Gratuit + Public | Gratuit + Privé | Pro/Équipe + Privé |
|---|:---:|:---:|:---:|
| Protection de branche / Règles | Oui | Non | Oui |
| Protection des tags (Règles) | Oui | Non | Oui |
| Alertes Dependabot | Oui | Non | Oui |
| Mises à jour de sécurité Dependabot | Oui | Non | Oui |
| Analyse des secrets | Auto | Non | Oui |
| Protection push | Oui | Non | Oui |
| Signalement privé de vulnérabilités | Oui | Oui | Oui |
| Graphe des dépendances | Auto | Non | Oui |

`gh-safe-repo` détecte votre niveau de plan et la visibilité du dépôt au moment de l'exécution. Les fonctionnalités indisponibles apparaissent comme `SKIP` dans la sortie du plan avec une raison claire — l'outil n'échoue jamais silencieusement.

---

## Fonctionnement```
gh-safe-repo create <owner/repo>
      │
      ├─ Parse owner/repo, validate owner matches authenticated user (create only)
      ├─ Load config (./gh-safe-repo.ini or $XDG_CONFIG_HOME/gh-safe-repo/gh-safe-repo.ini)
      ├─ Apply CLI flag overrides (--public, etc.)
      ├─ Authenticate via gh CLI or GITHUB_TOKEN
      ├─ GET /user → owner login + plan level  (single cached call)
      │
      ├─ Build plan (each plugin compares desired vs. current state)
      │   ├─ RepositoryPlugin  → repo creation + basic settings
      │   ├─ ActionsPlugin     → allowed actions, workflow permissions, SHA pinning
      │   ├─ BranchProtectionPlugin → Rulesets API (default; classic if use_rulesets = false)
      │   ├─ SecurityPlugin    → Dependabot, secret scanning, push protection, private vuln reporting
      │   └─ TagProtectionPlugin → immutable tags via Rulesets API
      │
      ├─ Print plan table
      │
      └─ Apply (unless --dry-run)
          ├─ POST /user/repos
          ├─ PATCH /repos/{owner}/{repo}       (settings)
          ├─ PUT  /repos/{owner}/{repo}/actions/permissions/workflow
          ├─ POST/PATCH /repos/{owner}/{repo}/rulesets  (branch protection; default)
          │   or PUT /repos/{owner}/{repo}/branches/main/protection (if use_rulesets = false)
          ├─ PUT  /repos/{owner}/{repo}/vulnerability-alerts
          ├─ PUT  /repos/{owner}/{repo}/automated-security-fixes
          ├─ PUT  /repos/{owner}/{repo}/private-vulnerability-reporting
          ├─ PATCH /repos/{owner}/{repo}  (security_and_analysis: push protection)
          ├─ POST /repos/{owner}/{repo}/rulesets  (tag protection ruleset)
          ├─ git clone --mirror + git push --mirror (if --from)
          └─ git clone <local> + git push --all --tags (if --local, git repo)
              or git init + add -A + commit + push (if --local, plain dir)

Architecture des plugins

Chaque catégorie de paramètres est une classe de plugin autonome (gh_safe_repo/plugins/). Chaque plugin :

  1. Récupère l'état actuel depuis l'API GitHub
  2. Compare avec l'état souhaité depuis la configuration
  3. Retourne un Plan (liste d'objets Change : ADD / UPDATE / DELETE / SKIP)
  4. N'applique que les changements réels — pas d'appels API pour les opérations sans effet

Cela signifie que le mode audit et le mode création utilisent le même chemin de planification/application. La seule différence est que l'état actuel est récupéré depuis un dépôt existant ou supposé être les paramètres par défaut de GitHub.

Authentification

Les appels API résolvent un jeton dans cet ordre :

  1. Variable d'environnement GITHUB_TOKEN — permet de cibler un compte spécifique sans changer la session gh active (et c'est la seule information d'identification nécessaire en CI)
  2. gh auth token — ce que gh auth login a configuré
  3. Erreur si aucun n'est disponible

Les jetons sont passés aux processus enfants gh api en tant que GH_TOKEN dans l'environnement du sous-processus et ne sont jamais consignés.

Les opérations Git (push et clone avec --local / --from) utilisent vos propres informations d'identification git — clé SSH ou assistant d'identification — par défaut, et non le jeton API. Dans les environnements sans aucune de ces options (par exemple, CI avec uniquement GITHUB_TOKEN), l'outil se rabat sur un push via HTTPS avec le jeton dans l'URL ; le paramètre de configuration [git_transport] mode contrôle cela (voir la référence de configuration). Les URL contenant des jetons ne sont jamais écrites dans le .git/config de votre dépôt et sont masquées dans toutes les sorties.

Approche API

Tous les appels à l'API GitHub passent par gh api via subprocess. Cela maintient l'authentification entièrement dans l'interface en ligne de commande gh — pas de code de gestion de jetons, pas de flux OAuth, pas de verrouillage de version PyGithub. Les corps de requête JSON sont passés via --input - (entrée standard), et non par les flags --field.


Développement```bash

Clone and set up

git clone https://github.com/your-username/gh-safe-repo cd gh-safe-repo uv sync # creates .venv, installs pytest

Run tests

uv run pytest tests/ -v

Run the tool directly (without installing)

./gh-safe-repo create <owner/repo> --dry-run

Install globally (picks up the current source)

uv tool install .

root@kitploit:~
Voir [`tests/README.md`](https://github.com/ariesq/gh-safe-repo/blob/HEAD/tests/README.md) pour les descriptions des fichiers de test, les conventions de simulation, et comment ajouter de nouveaux tests.

### Structure du projet```
gh-safe-repo/
├── gh-safe-repo          # Thin launcher (entry point for direct use)
├── gh_safe_repo/         # Package — see gh_safe_repo/README.md for internals
│   ├── cli.py            # Subparser dispatch (create, fix, scan)
│   ├── commands/         # Subcommand implementations
│   │   ├── _common.py    # Shared helpers, CLIContext, plan formatting
│   │   ├── create.py     # create subcommand
│   │   ├── fix.py        # fix subcommand
│   │   └── scan.py       # scan subcommand
│   └── plugins/          # Settings plugins (one per category)
├── pyproject.toml        # Build config, entry points
├── gh-safe-repo.ini.example  # Fully annotated example config
└── tests/

Consultez gh_safe_repo/README.md pour la carte des modules, l'architecture des plugins et un guide pour ajouter de nouveaux paramètres.

Politique de dépendances

Il n'y a aucune dépendance d'exécution. Tout utilise la bibliothèque standard Python (argparse, configparser, subprocess, json, re). N'ajoutez pas de paquets tiers sans discussion.

pytest est la seule dépendance de développement, déclarée comme une entrée [dependency-groups] native d'UV dans pyproject.toml.


Travaux antérieurs

Ces projets ont été étudiés lors de la conception et ont influencé l'architecture de gh-safe-repo. Ce sont des outils distincts avec des périmètres et des modèles utilisateur différents — consultez docs/LEARNINGS.md pour des notes techniques détaillées sur l'adaptation des motifs.

  • github/safe-settings — Application GitHub au niveau de l'organisation (Node.js/Probot) qui applique les paramètres de dépôt à partir d'une configuration centrale. Source du motif d'architecture des plugins (une classe par catégorie de paramètre, fetch → diff → apply) et de l'approche de comparaison mergeDeep.

  • repository-settings/app — Variante plus simple par dépôt de safe-settings, également en Node.js/Probot. A fourni une référence plus propre pour le motif de plugin de base Diffable.

  • nicholasgasior/gh-repo-settings — Extension CLI écrite en Go avec un workflow plan/apply. Inspiration principale pour le motif d'encapsulation du sous-processus gh api et la conception de la sortie du plan en dry-run.

Télécharger l’outil
OptionDescription
--publicCréer en tant que dépôt public (par défaut : privé)
--local PATHPousser le code d'un dépôt git local dans le nouveau dépôt. Exécute d'abord une analyse préalable. Mutuellement exclusif avec --from.
--from OWNER/REPOMiroir du code d'un dépôt existant dans le nouveau dépôt. Exécute une analyse préalable. Mutuellement exclusif avec --local.
--yes / -yIgnorer la demande de confirmation et appliquer immédiatement (pour une utilisation en script/lot)
--dry-runAfficher le plan sans apporter de modifications
--jsonÉmettre le plan au format JSON vers stdout au lieu du tableau ANSI
--config [PATH]Chemin vers le fichier de configuration ; --config seul utilise uniquement les valeurs par défaut intégrées
--debugAfficher chaque appel et réponse API
OptionDescription
--yes / -yIgnorer la demande de confirmation et appliquer immédiatement (pour une utilisation en script/lot)
--dry-runAfficher la différence des paramètres sans appliquer les modifications
--jsonÉmettre le plan au format JSON vers stdout au lieu du tableau ANSI
--config [PATH]Chemin vers le fichier de configuration ; --config seul utilise uniquement les valeurs par défaut intégrées
--debugAfficher chaque appel et réponse API, ainsi que l'identité résolue du dépôt (id, nom complet, type de propriétaire)
Action
Signification
ADD (vert)Nouveau paramètre appliqué
UPDATE (jaune)Paramètre existant modifié (mode audit)
DELETE (rouge)Paramètre supprimé
SKIP (gris)Aucune action requise — déjà à la valeur souhaitée, ou fonctionnalité indisponible dans votre combinaison plan/visibilité
CatégorieSévéritéExemples
Secrets codés en durCritiqueClés AWS (AKIA…), jetons GitHub (ghp_…, github_pat_…), clés privées, URL de bases de données
Chaînes interditesCritiqueToute chaîne littérale que vous configurez (noms d'utilisateur, noms d'hôtes internes, noms de code)
Fichiers de contexte IACritiqueCLAUDE.md, AGENTS.md, .cursorrules, copilot-instructions.md, .cursor/ — peuvent contenir des notes de développement internes ; l'historique Git peut être plus sensible que la version actuelle
Adresses e-mailAvertissementTout motif [email protected] dans l'arbre de travail et l'historique Git
Fichiers volumineuxAvertissementFichiers dépassant le seuil de taille configuré (par défaut : 100 Mo)
Commentaires TODO/FIXMEInfo# TODO, # FIXME, # HACK, # XXX