{"id":520,"date":"2026-03-08T12:13:44","date_gmt":"2026-03-08T11:13:44","guid":{"rendered":"https:\/\/secure-pipelines.com\/?p=520"},"modified":"2026-03-24T12:57:19","modified_gmt":"2026-03-24T11:57:19","slug":"lab-detecting-preventing-secret-leaks-ci-cd-pipelines","status":"publish","type":"post","link":"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/lab-detecting-preventing-secret-leaks-ci-cd-pipelines\/","title":{"rendered":"Lab : D\u00e9tection et Pr\u00e9vention des Fuites de Secrets dans les Pipelines CI\/CD"},"content":{"rendered":"<h2>Vue d&rsquo;ensemble<\/h2>\n<p>Les fuites de secrets dans les pipelines CI\/CD sont la cause num\u00e9ro un de compromission des pipelines. Les identifiants expos\u00e9s \u2014 cl\u00e9s API, mots de passe de bases de donn\u00e9es, jetons d&rsquo;acc\u00e8s cloud \u2014 offrent aux attaquants un acc\u00e8s direct aux syst\u00e8mes de production. Selon le rapport 2025 State of Secrets Sprawl de GitGuardian, plus de 12 millions de nouveaux secrets ont \u00e9t\u00e9 d\u00e9tect\u00e9s dans les commits publics GitHub en une seule ann\u00e9e.<\/p>\n<p>Le probl\u00e8me n&rsquo;est pas que les d\u00e9veloppeurs sont n\u00e9gligents. C&rsquo;est que la livraison logicielle moderne implique des dizaines de fichiers de configuration, de variables d&rsquo;environnement et de points d&rsquo;int\u00e9gration o\u00f9 les secrets peuvent accidentellement se retrouver dans le contr\u00f4le de version. Une seule cl\u00e9 AWS divulgu\u00e9e peut co\u00fbter \u00e0 une organisation des dizaines de milliers de dollars en quelques minutes.<\/p>\n<p>Ce lab pratique vous guide dans la mise en place d&rsquo;une strat\u00e9gie de d\u00e9tection de secrets multi-couches couvrant trois points de contr\u00f4le critiques :<\/p>\n<ul>\n<li><strong>Analyse pre-commit<\/strong> \u2014 Intercepter les secrets avant qu&rsquo;ils n&rsquo;atteignent le d\u00e9p\u00f4t.<\/li>\n<li><strong>Analyse dans le pipeline<\/strong> \u2014 Bloquer les pull requests et les push contenant des secrets.<\/li>\n<li><strong>Analyse post-commit et \u00e0 l&rsquo;ex\u00e9cution<\/strong> \u2014 D\u00e9tecter les secrets qui passent entre les mailles du filet et d\u00e9clencher la rem\u00e9diation.<\/li>\n<\/ul>\n<p>\u00c0 la fin de ce lab, vous disposerez d&rsquo;une configuration de d\u00e9fense en profondeur fonctionnelle utilisant gitleaks, truffleHog, GitHub secret scanning et des r\u00e8gles de d\u00e9tection personnalis\u00e9es.<\/p>\n<h2>Pr\u00e9requis<\/h2>\n<p>Avant de commencer, assurez-vous de disposer des \u00e9l\u00e9ments suivants :<\/p>\n<ul>\n<li><strong>Git 2.30+<\/strong> install\u00e9 et configur\u00e9.<\/li>\n<li><strong>Python 3.8+<\/strong> avec <code>pip<\/code> disponible.<\/li>\n<li><strong>Docker<\/strong> (optionnel, mais recommand\u00e9 pour l&rsquo;analyse conteneuris\u00e9e).<\/li>\n<li>Un <strong>compte GitHub<\/strong> avec acc\u00e8s pour cr\u00e9er des d\u00e9p\u00f4ts (requis pour l&rsquo;exercice GitHub secret scanning).<\/li>\n<li>Un <strong>terminal<\/strong> (macOS, Linux ou WSL sous Windows).<\/li>\n<\/ul>\n<p>Aucun vrai secret ni compte cloud n&rsquo;est n\u00e9cessaire. Nous utiliserons des secrets de test intentionnellement plant\u00e9s tout au long de ce lab.<\/p>\n<h2>Mise en Place de l&rsquo;Environnement<\/h2>\n<h3>\u00c9tape 1 : Cr\u00e9er un D\u00e9p\u00f4t de Test<\/h3>\n<p>Commencez par cr\u00e9er un d\u00e9p\u00f4t Git vierge que nous utiliserons pour tous les exercices :<\/p>\n<pre><code>mkdir secret-leak-lab &amp;&amp; cd secret-leak-lab\ngit init\necho \"# Secret Leak Detection Lab\" &gt; README.md\ngit add README.md\ngit commit -m \"Initial commit\"<\/code><\/pre>\n<h3>\u00c9tape 2 : Planter des Secrets de Test Intentionnels<\/h3>\n<p>Nous avons besoin de secrets r\u00e9alistes (mais faux) \u00e0 diff\u00e9rents emplacements pour simuler un sc\u00e9nario r\u00e9el. Cr\u00e9ez les fichiers suivants :<\/p>\n<p><strong>Un fichier <code>.env<\/code> avec des identifiants de base de donn\u00e9es :<\/strong><\/p>\n<pre><code>cat &gt; .env &lt;&lt;'EOF'\nDB_HOST=localhost\nDB_PORT=5432\nDB_USER=admin\nDB_PASSWORD=SuperSecret123!\nDB_NAME=production_db\nSECRET_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6\nEOF<\/code><\/pre>\n<p><strong>Un script Python avec une cl\u00e9 AWS cod\u00e9e en dur :<\/strong><\/p>\n<pre><code>cat &gt; deploy.py &lt;&lt;'EOF'\nimport boto3\n\n# WARNING: These are intentionally fake credentials for testing\nAWS_ACCESS_KEY_ID = \"AKIAIOSFODNN7EXAMPLE\"\nAWS_SECRET_ACCESS_KEY = \"wJalrXUtnFEMI\/K7MDENG\/bPxRfiCYEXAMPLEKEY\"\n\ndef deploy_to_s3(bucket, file_path):\n    s3 = boto3.client(\n        's3',\n        aws_access_key_id=AWS_ACCESS_KEY_ID,\n        aws_secret_access_key=AWS_SECRET_ACCESS_KEY\n    )\n    s3.upload_file(file_path, bucket, file_path)\n    print(f\"Deployed {file_path} to s3:\/\/{bucket}\")\n\nif __name__ == \"__main__\":\n    deploy_to_s3(\"my-app-bucket\", \"dist\/app.zip\")\nEOF<\/code><\/pre>\n<p><strong>Un fichier YAML de configuration avec une cha\u00eene de connexion \u00e0 la base de donn\u00e9es :<\/strong><\/p>\n<pre><code>cat &gt; config.yml &lt;&lt;'EOF'\napp:\n  name: my-application\n  environment: production\n\ndatabase:\n  url: \"postgresql:\/\/admin:SuperSecret123!@db.example.com:5432\/prod\"\n  pool_size: 10\n\nredis:\n  url: \"redis:\/\/:MyRedisPassword@cache.example.com:6379\/0\"\nEOF<\/code><\/pre>\n<p><strong>Un Dockerfile avec une cl\u00e9 API dans une instruction ENV :<\/strong><\/p>\n<pre><code>cat &gt; Dockerfile &lt;&lt;'EOF'\nFROM python:3.11-slim\n\nWORKDIR \/app\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\n\n# WARNING: Never do this in production\nENV API_KEY=sk-proj-abc123def456ghi789jkl012mno345pqr678stu901vwx234\nENV STRIPE_SECRET_KEY=sk_live_4eC39HqLyjWDarjtT1zdp7dc\n\nCOPY . .\nCMD [\"python\", \"app.py\"]\nEOF<\/code><\/pre>\n<h3>\u00c9tape 3 : V\u00e9rifier l&rsquo;\u00c9tat Initial<\/h3>\n<p>\u00c0 ce stade, rien n&#8217;emp\u00eache ces secrets d&rsquo;\u00eatre commit\u00e9s :<\/p>\n<pre><code>git add -A\ngit status<\/code><\/pre>\n<p>Git met en staging tout sans probl\u00e8me, secrets inclus. Il n&rsquo;y a pas de hooks, pas d&rsquo;analyse, pas de garde-fous. C&rsquo;est l&rsquo;\u00e9tat dans lequel se trouvent la plupart des d\u00e9p\u00f4ts au d\u00e9part. Notre objectif est de changer cela.<\/p>\n<pre><code># Reset staging so we can test scanning before committing\ngit reset HEAD<\/code><\/pre>\n<h2>Exercice 1 : Analyse Pre-commit avec gitleaks<\/h2>\n<p><a href=\"https:\/\/github.com\/gitleaks\/gitleaks\" target=\"_blank\" rel=\"noopener\">Gitleaks<\/a> est un outil open-source con\u00e7u pour d\u00e9tecter les secrets cod\u00e9s en dur dans les d\u00e9p\u00f4ts Git. Il prend en charge l&rsquo;analyse du r\u00e9pertoire de travail, de l&rsquo;historique des commits et peut s&rsquo;ex\u00e9cuter comme hook pre-commit pour bloquer les secrets avant qu&rsquo;ils ne soient commit\u00e9s.<\/p>\n<h3>Installer gitleaks<\/h3>\n<p>Choisissez votre m\u00e9thode d&rsquo;installation pr\u00e9f\u00e9r\u00e9e :<\/p>\n<pre><code># macOS (Homebrew)\nbrew install gitleaks\n\n# Docker\ndocker pull zricethezav\/gitleaks:latest\n\n# Go (from source)\ngo install github.com\/gitleaks\/gitleaks\/v8@latest<\/code><\/pre>\n<p>V\u00e9rifiez l&rsquo;installation :<\/p>\n<pre><code>gitleaks version<\/code><\/pre>\n<h3>Ex\u00e9cuter gitleaks Manuellement<\/h3>\n<p>Analysez le r\u00e9pertoire de travail \u00e0 la recherche de secrets :<\/p>\n<pre><code>gitleaks detect --source . -v<\/code><\/pre>\n<p>Vous devriez voir une sortie similaire \u00e0 la suivante :<\/p>\n<pre><code>Finding:     AWS_ACCESS_KEY_ID = \"AKIAIOSFODNN7EXAMPLE\"\nSecret:      AKIAIOSFODNN7EXAMPLE\nRuleID:      aws-access-key-id\nEntropy:     3.52\nFile:        deploy.py\nLine:        4\n\nFinding:     AWS_SECRET_ACCESS_KEY = \"wJalrXUtnFEMI\/K7MDENG\/bPxRfiCYEXAMPLEKEY\"\nSecret:      wJalrXUtnFEMI\/K7MDENG\/bPxRfiCYEXAMPLEKEY\nRuleID:      aws-secret-access-key\nEntropy:     4.71\nFile:        deploy.py\nLine:        5\n\nFinding:     DB_PASSWORD=SuperSecret123!\nSecret:      SuperSecret123!\nRuleID:      generic-credential\nEntropy:     3.40\nFile:        .env\nLine:        4\n\nFinding:     STRIPE_SECRET_KEY=sk_live_4eC39HqLyjWDarjtT1zdp7dc\nSecret:      sk_live_4eC39HqLyjWDarjtT1zdp7dc\nRuleID:      stripe-secret-key\nEntropy:     4.20\nFile:        Dockerfile\nLine:        9\n\n12:14PM INF 6 commits scanned.\n12:14PM WRN leaks found: 6<\/code><\/pre>\n<p>Gitleaks identifie correctement les cl\u00e9s AWS, les identifiants g\u00e9n\u00e9riques, les cl\u00e9s Stripe, et plus encore. Chaque r\u00e9sultat inclut le fichier, le num\u00e9ro de ligne et la r\u00e8gle de d\u00e9tection qui s&rsquo;est d\u00e9clench\u00e9e.<\/p>\n<h3>Configurer gitleaks comme Hook Pre-commit<\/h3>\n<p>Le framework <a href=\"https:\/\/pre-commit.com\/\" target=\"_blank\" rel=\"noopener\">pre-commit<\/a> facilite l&rsquo;ex\u00e9cution automatique de gitleaks avant chaque commit. Installez d&rsquo;abord pre-commit :<\/p>\n<pre><code>pip install pre-commit<\/code><\/pre>\n<p>Cr\u00e9ez un fichier <code>.pre-commit-config.yaml<\/code> \u00e0 la racine de votre d\u00e9p\u00f4t :<\/p>\n<pre><code>repos:\n  - repo: https:\/\/github.com\/gitleaks\/gitleaks\n    rev: v8.21.2\n    hooks:\n      - id: gitleaks<\/code><\/pre>\n<p>Installez le hook :<\/p>\n<pre><code>pre-commit install<\/code><\/pre>\n<h3>Tester le Hook : Commiter un Secret (Bloqu\u00e9)<\/h3>\n<pre><code>git add deploy.py\ngit commit -m \"Add deployment script\"<\/code><\/pre>\n<p>Le commit est bloqu\u00e9 :<\/p>\n<pre><code>Detect hardcoded secrets.................................................Failed\n- hook id: gitleaks\n- exit code: 1\n\n12:15PM WRN leaks found: 2\n<\/code><\/pre>\n<p>Le hook pre-commit arr\u00eate compl\u00e8tement le commit. Le secret n&rsquo;entre jamais dans l&rsquo;historique Git.<\/p>\n<h3>Tester le Hook : Commiter du Code Propre (R\u00e9ussi)<\/h3>\n<p>Cr\u00e9ez un fichier sans secrets :<\/p>\n<pre><code>cat &gt; utils.py &lt;&lt;'EOF'\ndef format_date(date_obj):\n    return date_obj.strftime(\"%Y-%m-%d\")\n\ndef sanitize_input(user_input):\n    return user_input.strip().replace(\"&lt;\", \"&amp;lt;\").replace(\"&gt;\", \"&amp;gt;\")\nEOF\n\ngit add utils.py\ngit commit -m \"Add utility functions\"<\/code><\/pre>\n<p>Sortie :<\/p>\n<pre><code>Detect hardcoded secrets.................................................Passed\n[main abc1234] Add utility functions\n 1 file changed, 5 insertions(+)\n<\/code><\/pre>\n<p>Le code propre passe sans probl\u00e8me.<\/p>\n<h2>Exercice 2 : Analyse dans le Pipeline avec gitleaks dans GitHub Actions<\/h2>\n<p>Les hooks pre-commit sont une premi\u00e8re couche solide, mais ils s&rsquo;ex\u00e9cutent localement et peuvent \u00eatre contourn\u00e9s. L&rsquo;analyse dans le pipeline ajoute une couche d&rsquo;application c\u00f4t\u00e9 serveur qui ne peut pas \u00eatre ignor\u00e9e.<\/p>\n<h3>Cr\u00e9er le Workflow GitHub Actions<\/h3>\n<p>Cr\u00e9ez le fichier <code>.github\/workflows\/secret-scan.yml<\/code> avec le contenu suivant :<\/p>\n<pre><code>name: Secret Scanning\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n\njobs:\n  gitleaks:\n    name: Detect Secrets with gitleaks\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions\/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Run gitleaks\n        uses: gitleaks\/gitleaks-action@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}\n<\/code><\/pre>\n<p>Le param\u00e8tre <code>fetch-depth: 0<\/code> est critique \u2014 il garantit que l&rsquo;historique Git complet est disponible afin que gitleaks puisse analyser tous les commits, et pas seulement le dernier.<\/p>\n<h3>Comment Cela Fonctionne en Pratique<\/h3>\n<p><strong>Sc\u00e9nario A : Une PR avec un secret divulgu\u00e9.<\/strong> Un d\u00e9veloppeur ajoute accidentellement une cl\u00e9 API dans un fichier de configuration et ouvre une pull request. L&rsquo;action gitleaks analyse le diff, d\u00e9tecte le secret et marque la v\u00e9rification comme \u00e9chou\u00e9e. La PR ne peut pas \u00eatre fusionn\u00e9e tant que le secret n&rsquo;est pas supprim\u00e9.<\/p>\n<p><strong>Sc\u00e9nario B : Une PR propre.<\/strong> Un d\u00e9veloppeur ouvre une PR avec de la logique applicative et aucun secret. L&rsquo;action gitleaks analyse le diff, ne trouve rien et marque la v\u00e9rification comme r\u00e9ussie. La PR peut passer \u00e0 la revue de code et \u00eatre fusionn\u00e9e.<\/p>\n<p>Pour appliquer cette r\u00e8gle, acc\u00e9dez \u00e0 <strong>Settings \u2192 Branches \u2192 Branch protection rules<\/strong> de votre d\u00e9p\u00f4t et ajoutez <code>gitleaks<\/code> comme v\u00e9rification de statut requise pour la branche <code>main<\/code>. Cela emp\u00eache quiconque de fusionner une PR qui \u00e9choue \u00e0 l&rsquo;analyse de secrets.<\/p>\n<h2>Exercice 3 : Analyse dans le Pipeline avec truffleHog<\/h2>\n<p><a href=\"https:\/\/github.com\/trufflesecurity\/trufflehog\" target=\"_blank\" rel=\"noopener\">TruffleHog<\/a> adopte une approche diff\u00e9rente de la d\u00e9tection de secrets. En plus de la correspondance de motifs, il peut <strong>v\u00e9rifier<\/strong> si les secrets d\u00e9tect\u00e9s sont r\u00e9ellement actifs en les testant contre l&rsquo;API du service correspondant.<\/p>\n<h3>Installer truffleHog<\/h3>\n<pre><code># pip\npip install trufflehog\n\n# Docker\ndocker pull trufflesecurity\/trufflehog:latest\n\n# Homebrew\nbrew install trufflehog<\/code><\/pre>\n<h3>Ex\u00e9cuter truffleHog sur le D\u00e9p\u00f4t de Test<\/h3>\n<pre><code># Scan the local repo\ntrufflehog git file:\/\/. --only-verified<\/code><\/pre>\n<p>Le flag <code>--only-verified<\/code> indique \u00e0 truffleHog de ne signaler que les secrets qu&rsquo;il a confirm\u00e9s comme actifs. Cela r\u00e9duit consid\u00e9rablement les faux positifs. Si vous souhaitez voir tous les r\u00e9sultats, y compris les non v\u00e9rifi\u00e9s, omettez le flag :<\/p>\n<pre><code># Show all findings (verified and unverified)\ntrufflehog git file:\/\/.<\/code><\/pre>\n<p><strong>V\u00e9rifi\u00e9 vs. Non v\u00e9rifi\u00e9 :<\/strong> Un secret <em>v\u00e9rifi\u00e9<\/em> est un secret que truffleHog a test\u00e9 contre l&rsquo;API du fournisseur et confirm\u00e9 comme actif. Par exemple, il tentera de s&rsquo;authentifier avec une cl\u00e9 AWS pour voir si elle fonctionne. Un secret <em>non v\u00e9rifi\u00e9<\/em> correspond \u00e0 un motif connu mais n&rsquo;a pas \u00e9t\u00e9 confirm\u00e9 comme actif \u2014 il peut s&rsquo;agir d&rsquo;une cl\u00e9 r\u00e9voqu\u00e9e, d&rsquo;un placeholder ou d&rsquo;un faux positif.<\/p>\n<h3>Cr\u00e9er un Job de Pipeline GitLab CI<\/h3>\n<p>TruffleHog s&rsquo;int\u00e8gre bien dans GitLab CI. Ajoutez ce qui suit \u00e0 votre <code>.gitlab-ci.yml<\/code> :<\/p>\n<pre><code>stages:\n  - security\n\nsecret-scan:\n  stage: security\n  image:\n    name: trufflesecurity\/trufflehog:latest\n    entrypoint: [\"\"]\n  script:\n    - trufflehog git file:\/\/. --fail --json &gt; trufflehog-results.json\n  artifacts:\n    when: always\n    paths:\n      - trufflehog-results.json\n    expire_in: 30 days\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\"'\n    - if: '$CI_COMMIT_BRANCH == \"main\"'\n<\/code><\/pre>\n<p>Le flag <code>--fail<\/code> fait en sorte que truffleHog termine avec un code de sortie non nul si des secrets sont trouv\u00e9s, ce qui fait \u00e9chouer le pipeline. Le flag <code>--json<\/code> produit des r\u00e9sultats structur\u00e9s qui peuvent \u00eatre analys\u00e9s par d&rsquo;autres outils ou tableaux de bord.<\/p>\n<h3>gitleaks vs. truffleHog : Quand Utiliser Lequel<\/h3>\n<table>\n<thead>\n<tr>\n<th>Fonctionnalit\u00e9<\/th>\n<th>gitleaks<\/th>\n<th>truffleHog<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>M\u00e9thode de d\u00e9tection<\/td>\n<td>Regex + entropie<\/td>\n<td>Regex + entropie + v\u00e9rification<\/td>\n<\/tr>\n<tr>\n<td>V\u00e9rification des secrets<\/td>\n<td>Non<\/td>\n<td>Oui (teste si le secret est actif)<\/td>\n<\/tr>\n<tr>\n<td>Rapidit\u00e9<\/td>\n<td>Tr\u00e8s rapide<\/td>\n<td>Plus lent (en raison de la v\u00e9rification)<\/td>\n<\/tr>\n<tr>\n<td>Taux de faux positifs<\/td>\n<td>Mod\u00e9r\u00e9<\/td>\n<td>Faible (avec &#8211;only-verified)<\/td>\n<\/tr>\n<tr>\n<td>R\u00e8gles personnalis\u00e9es<\/td>\n<td>Oui (.gitleaks.toml)<\/td>\n<td>Oui (d\u00e9tecteurs personnalis\u00e9s)<\/td>\n<\/tr>\n<tr>\n<td>Support pre-commit<\/td>\n<td>Natif<\/td>\n<td>Via script wrapper<\/td>\n<\/tr>\n<tr>\n<td>Id\u00e9al pour<\/td>\n<td>V\u00e9rifications rapides pre-commit et PR<\/td>\n<td>Analyses approfondies et v\u00e9rification<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Recommandation :<\/strong> Utilisez gitleaks pour les hooks pre-commit rapides et les v\u00e9rifications de PR. Utilisez truffleHog pour les analyses approfondies p\u00e9riodiques et lorsque vous avez besoin de r\u00e9sultats v\u00e9rifi\u00e9s pour prioriser la rem\u00e9diation.<\/p>\n<h2>Exercice 4 : GitHub Secret Scanning et Push Protection<\/h2>\n<p>GitHub propose une analyse de secrets int\u00e9gr\u00e9e qui fonctionne au niveau de la plateforme. Contrairement \u00e0 gitleaks et truffleHog, que vous installez et configurez vous-m\u00eame, GitHub secret scanning est int\u00e9gr\u00e9 directement dans les param\u00e8tres du d\u00e9p\u00f4t.<\/p>\n<h3>Activer Secret Scanning<\/h3>\n<ol>\n<li>Acc\u00e9dez \u00e0 votre d\u00e9p\u00f4t sur GitHub.<\/li>\n<li>Naviguez vers <strong>Settings \u2192 Code security and analysis<\/strong>.<\/li>\n<li>Activez <strong>Secret scanning<\/strong>.<\/li>\n<li>Activez <strong>Push protection<\/strong>.<\/li>\n<\/ol>\n<p>Push protection est la fonctionnalit\u00e9 cl\u00e9 ici. Lorsqu&rsquo;elle est activ\u00e9e, GitHub bloque tout push contenant un motif de secret reconnu avant qu&rsquo;il n&rsquo;atteigne le d\u00e9p\u00f4t.<\/p>\n<h3>Tester Push Protection<\/h3>\n<p>Tentez de pousser un commit contenant un motif de secret connu, tel qu&rsquo;une cl\u00e9 d&rsquo;acc\u00e8s AWS ou un jeton d&rsquo;acc\u00e8s personnel GitHub :<\/p>\n<pre><code># Stage and commit a file with a test secret\ngit add deploy.py\ngit commit -m \"Add deploy script\"\ngit push origin main<\/code><\/pre>\n<p>GitHub bloque le push avec un message comme :<\/p>\n<pre><code>remote: error: GH013: Repository rule violations found for refs\/heads\/main.\nremote:\n remote: - GITHUB PUSH PROTECTION\nremote:   \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\nremote:     Resolve the following violations before pushing again\nremote:\nremote:     \u2014 Push cannot contain secrets \u2014\nremote:\nremote:\nremote:      (?) To push, remove secret from commit(s) or follow this URL to allow the secret.\nremote:\nremote:      \u2014 Amazon AWS Access Key ID \u2014\nremote:        locations:\n remote:          - commit: abc1234def5678\n remote:            path: deploy.py:4\nremote:\n! [remote rejected] main -&gt; main (push rule violations)\nerror: failed to push some refs<\/code><\/pre>\n<h3>G\u00e9rer les Faux Positifs<\/h3>\n<p>Si GitHub signale une valeur qui n&rsquo;est pas un vrai secret (par exemple, un fixture de test ou un exemple de documentation), vous pouvez contourner push protection avec une raison. GitHub fournit une URL dans le message de rejet o\u00f9 vous pouvez :<\/p>\n<ul>\n<li>S\u00e9lectionner une raison de contournement : <strong>\u00ab\u00a0It&rsquo;s used in tests\u00a0\u00bb<\/strong>, <strong>\u00ab\u00a0It&rsquo;s a false positive\u00a0\u00bb<\/strong> ou <strong>\u00ab\u00a0I&rsquo;ll fix it later\u00a0\u00bb<\/strong>.<\/li>\n<li>Soumettre le contournement, ce qui autorise le push mais enregistre l&rsquo;\u00e9v\u00e9nement pour l&rsquo;audit.<\/li>\n<\/ul>\n<p>Les administrateurs de l&rsquo;organisation peuvent voir tous les contournements dans le tableau de bord <strong>Security \u2192 Secret scanning<\/strong>.<\/p>\n<h3>Le Programme Partenaire<\/h3>\n<p>GitHub collabore avec plus de 200 fournisseurs de services (AWS, Stripe, Twilio, SendGrid et autres) via son <strong>programme partenaire de secret scanning<\/strong>. Lorsqu&rsquo;un secret d&rsquo;un partenaire est d\u00e9tect\u00e9 :<\/p>\n<ol>\n<li>GitHub notifie automatiquement le fournisseur de services.<\/li>\n<li>Le fournisseur r\u00e9voque l&rsquo;identifiant compromis.<\/li>\n<li>Le propri\u00e9taire du d\u00e9p\u00f4t est notifi\u00e9 par e-mail et via l&rsquo;onglet Security.<\/li>\n<\/ol>\n<p>Cela signifie que m\u00eame si un secret passe \u00e0 travers toutes les autres d\u00e9fenses et atteint un d\u00e9p\u00f4t public, la fen\u00eatre de dommages peut \u00eatre r\u00e9duite \u00e0 quelques minutes gr\u00e2ce \u00e0 la r\u00e9vocation automatique.<\/p>\n<h2>Exercice 5 : Motifs de Secrets Personnalis\u00e9s<\/h2>\n<p>Les r\u00e8gles de d\u00e9tection par d\u00e9faut couvrent les fournisseurs courants (AWS, Stripe, GitHub, Google Cloud, etc.), mais la plupart des organisations ont \u00e9galement des secrets internes avec des formats personnalis\u00e9s que les outils standards ne d\u00e9tecteront pas. Gitleaks prend en charge les r\u00e8gles personnalis\u00e9es via un fichier de configuration <code>.gitleaks.toml<\/code>.<\/p>\n<h3>Cr\u00e9er une Configuration gitleaks Personnalis\u00e9e<\/h3>\n<p>Cr\u00e9ez un fichier <code>.gitleaks.toml<\/code> \u00e0 la racine du d\u00e9p\u00f4t :<\/p>\n<pre><code>[extend]\n# Extend the default gitleaks configuration\n# useDefault = true\n\n[[rules]]\nid = \"mycompany-api-key\"\ndescription = \"MyCompany Internal API Key\"\nregex = '''MYCOMPANY-KEY-[A-Za-z0-9]{32}'''\ntags = [\"internal\", \"api-key\"]\nkeywords = [\"mycompany-key\"]\n\n[[rules]]\nid = \"internal-database-url\"\ndescription = \"Internal Database Connection String\"\nregex = '''postgresql:\/\/[^:]+:[^@]+@internal-db\\.[a-z0-9-]+\\.corp\\.[a-z]+\\.com'''\ntags = [\"internal\", \"database\"]\nkeywords = [\"internal-db\"]\n\n[[rules]]\nid = \"internal-jwt-signing-key\"\ndescription = \"Internal JWT Signing Key\"\nregex = '''JWT_SIGNING_KEY=[A-Za-z0-9+\/=]{64,}'''\ntags = [\"internal\", \"jwt\"]\nkeywords = [\"jwt_signing_key\"]\n\n[allowlist]\ndescription = \"Global allowlist\"\npaths = [\n  '''(.*?)test(.*?)\\.py''',\n  '''(.*?)_test\\.go''',\n  '''(.*?)spec(.*?)\\.js''',\n  '''(.*?)fixtures(.*?)''',\n  '''README\\.md'''\n]\n\n[[rules.allowlist]]\nid = \"mycompany-api-key\"\nregexes = [\n  '''MYCOMPANY-KEY-EXAMPLE[A-Za-z0-9]{24}''',\n  '''MYCOMPANY-KEY-TEST[A-Za-z0-9]{28}'''\n]\n<\/code><\/pre>\n<h3>Comprendre la Configuration<\/h3>\n<ul>\n<li><strong>R\u00e8gles personnalis\u00e9es :<\/strong> Les sections <code>[[rules]]<\/code> d\u00e9finissent des motifs sp\u00e9cifiques \u00e0 votre organisation. Le champ <code>regex<\/code> utilise des expressions r\u00e9guli\u00e8res compatibles Go. Le champ <code>keywords<\/code> aide gitleaks \u00e0 filtrer rapidement les fichiers \u2014 seuls les fichiers contenant le mot-cl\u00e9 sont analys\u00e9s avec la regex compl\u00e8te, ce qui am\u00e9liore les performances.<\/li>\n<li><strong>Liste d&rsquo;autorisation globale :<\/strong> La section <code>[allowlist]<\/code> d\u00e9finit les chemins qui doivent \u00eatre exclus de toute analyse. Les fichiers de test, les fixtures et la documentation sont des exclusions courantes.<\/li>\n<li><strong>Liste d&rsquo;autorisation par r\u00e8gle :<\/strong> La section <code>[[rules.allowlist]]<\/code> d\u00e9finit des exceptions pour des r\u00e8gles sp\u00e9cifiques. Ici, nous excluons les cl\u00e9s d&rsquo;exemple connues qui apparaissent dans la documentation ou les helpers de test.<\/li>\n<\/ul>\n<h3>Tester la Configuration Personnalis\u00e9e<\/h3>\n<p>Cr\u00e9ez un fichier avec un secret personnalis\u00e9 pour tester :<\/p>\n<pre><code>cat &gt; internal-config.py &lt;&lt;'EOF'\nMYCOMPANY_API_KEY = \"MYCOMPANY-KEY-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6\"\nEOF<\/code><\/pre>\n<p>Ex\u00e9cutez gitleaks avec la configuration personnalis\u00e9e :<\/p>\n<pre><code>gitleaks detect --source . --config .gitleaks.toml -v<\/code><\/pre>\n<p>La r\u00e8gle personnalis\u00e9e d\u00e9tecte la cl\u00e9 API interne qui aurait \u00e9t\u00e9 manqu\u00e9e par les r\u00e8gles par d\u00e9faut.<\/p>\n<h2>Construire une Strat\u00e9gie de D\u00e9fense en Profondeur<\/h2>\n<p>Aucune couche unique de d\u00e9tection de secrets n&rsquo;est suffisante. Les d\u00e9veloppeurs peuvent ignorer les hooks pre-commit. Les analyses de pipeline ne d\u00e9tectent les secrets qu&rsquo;au moment de la PR. GitHub push protection ne couvre que les motifs des fournisseurs connus. Une strat\u00e9gie robuste superpose toutes ces couches.<\/p>\n<h3>Les Cinq Couches de D\u00e9fense des Secrets<\/h3>\n<pre><code>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Couche 1 : Hook Pre-commit (gitleaks)              \u2502\n\u2502  \u2192 Intercepte les secrets avant l'historique local   \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Couche 2 : Analyse PR \/ Merge Request (gitleaks)   \u2502\n\u2502  \u2192 Bloque les PR contenant des secrets               \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Couche 3 : Push Protection (GitHub \/ GitLab)       \u2502\n\u2502  \u2192 Blocage au niveau plateforme des motifs connus    \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Couche 4 : Analyse Post-merge (truffleHog planifi\u00e9)\u2502\n\u2502  \u2192 Analyse approfondie hebdomadaire avec v\u00e9rification\u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Couche 5 : Surveillance Runtime (logs d'audit vault)\u2502\n\u2502  \u2192 D\u00e9tection d'anomalies d'utilisation des secrets   \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/code><\/pre>\n<h3>Pourquoi Aucune Couche Unique ne Suffit<\/h3>\n<ul>\n<li><strong>Les hooks pre-commit<\/strong> peuvent \u00eatre contourn\u00e9s avec <code>git commit --no-verify<\/code> ou en utilisant un client Git qui ne prend pas en charge les hooks.<\/li>\n<li><strong>Les analyses de pipeline<\/strong> ne s&rsquo;ex\u00e9cutent que sur les branches qui d\u00e9clenchent la CI \u2014 les push directs vers des branches non prot\u00e9g\u00e9es ou les force push peuvent les ignorer.<\/li>\n<li><strong>Push protection<\/strong> ne d\u00e9tecte que les motifs des fournisseurs connus \u2014 les secrets internes personnalis\u00e9s ne sont pas couverts.<\/li>\n<li><strong>Les analyses post-merge<\/strong> sont r\u00e9actives \u2014 elles trouvent les secrets apr\u00e8s qu&rsquo;ils sont d\u00e9j\u00e0 dans le d\u00e9p\u00f4t.<\/li>\n<\/ul>\n<p>Chaque couche compense les faiblesses des autres. Ensemble, elles cr\u00e9ent un syst\u00e8me o\u00f9 un secret devrait contourner les cinq couches pour passer inaper\u00e7u.<\/p>\n<h3>Workflow Combin\u00e9 : Analyse de PR et Analyse Compl\u00e8te Hebdomadaire<\/h3>\n<p>Voici un workflow GitHub Actions combin\u00e9 qui ex\u00e9cute gitleaks sur chaque PR et effectue une analyse compl\u00e8te du d\u00e9p\u00f4t chaque semaine :<\/p>\n<pre><code>name: Secret Scanning (Multi-Layer)\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n  schedule:\n    # Full repository scan every Monday at 6:00 AM UTC\n    - cron: '0 6 * * 1'\n\njobs:\n  # Layer 2: PR and push scanning\n  gitleaks-pr-scan:\n    name: gitleaks PR Scan\n    runs-on: ubuntu-latest\n    if: github.event_name == 'push' || github.event_name == 'pull_request'\n    steps:\n      - name: Checkout code\n        uses: actions\/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Run gitleaks (diff scan)\n        uses: gitleaks\/gitleaks-action@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n  # Layer 4: Weekly deep scan with truffleHog\n  trufflehog-full-scan:\n    name: truffleHog Full Repository Scan\n    runs-on: ubuntu-latest\n    if: github.event_name == 'schedule'\n    steps:\n      - name: Checkout code\n        uses: actions\/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Install truffleHog\n        run: pip install trufflehog\n\n      - name: Run truffleHog (full scan with verification)\n        run: |\n          trufflehog git file:\/\/. --fail --json &gt; trufflehog-results.json || true\n          if [ -s trufflehog-results.json ]; then\n            echo \"::error::Secrets detected in repository. See trufflehog-results.json.\"\n            cat trufflehog-results.json | python -m json.tool\n            exit 1\n          fi\n\n      - name: Upload scan results\n        if: always()\n        uses: actions\/upload-artifact@v4\n        with:\n          name: trufflehog-results\n          path: trufflehog-results.json\n          retention-days: 90\n<\/code><\/pre>\n<p>Ce workflow garantit que chaque modification de code est analys\u00e9e en temps r\u00e9el, et que l&rsquo;ensemble de l&rsquo;historique du d\u00e9p\u00f4t est audit\u00e9 chaque semaine pour d\u00e9tecter les secrets qui auraient pu passer inaper\u00e7us.<\/p>\n<h2>Nettoyage<\/h2>\n<p>Apr\u00e8s avoir termin\u00e9 le lab, supprimez les secrets de test et r\u00e9initialisez le d\u00e9p\u00f4t :<\/p>\n<pre><code># Remove test files with secrets\nrm -f .env deploy.py config.yml Dockerfile internal-config.py\n\n# Remove test configurations (optional \u2014 keep if you want to reuse them)\n# rm -f .gitleaks.toml .pre-commit-config.yaml\n\n# Commit the cleanup\ngit add -A\ngit commit -m \"Remove test secrets from lab exercises\"\n\n# If you want to completely remove secrets from Git history,\n# use git-filter-repo (more thorough than git filter-branch):\npip install git-filter-repo\ngit filter-repo --invert-paths --path deploy.py --path .env --path config.yml --path Dockerfile\n<\/code><\/pre>\n<p><strong>Important :<\/strong> La simple suppression de fichiers ne les retire pas de l&rsquo;historique Git. Toute personne ayant acc\u00e8s au d\u00e9p\u00f4t peut encore trouver les secrets dans les commits pass\u00e9s. Utilisez <code>git-filter-repo<\/code> pour r\u00e9\u00e9crire l&rsquo;historique et supprimer d\u00e9finitivement les fichiers sensibles. Apr\u00e8s la r\u00e9\u00e9criture de l&rsquo;historique, faites un force-push vers le remote et demandez \u00e0 tous les collaborateurs de re-cloner le d\u00e9p\u00f4t.<\/p>\n<h2>Points Cl\u00e9s \u00e0 Retenir<\/h2>\n<ul>\n<li><strong>Les secrets dans les pipelines CI\/CD sont le vecteur d&rsquo;attaque le plus courant pour la compromission des pipelines.<\/strong> Un seul identifiant divulgu\u00e9 peut donner \u00e0 un attaquant un acc\u00e8s complet \u00e0 l&rsquo;infrastructure de production.<\/li>\n<li><strong>Les hooks pre-commit avec gitleaks offrent la boucle de r\u00e9troaction la plus rapide.<\/strong> Les d\u00e9veloppeurs sont alert\u00e9s imm\u00e9diatement, avant que le secret n&rsquo;entre dans l&rsquo;historique Git.<\/li>\n<li><strong>L&rsquo;analyse dans le pipeline est une couche d&rsquo;application obligatoire.<\/strong> Elle ne peut pas \u00eatre contourn\u00e9e par les d\u00e9veloppeurs et garantit qu&rsquo;aucune PR contenant des secrets n&rsquo;est fusionn\u00e9e.<\/li>\n<li><strong>La capacit\u00e9 de v\u00e9rification de truffleHog r\u00e9duit consid\u00e9rablement les faux positifs.<\/strong> Utilisez-le pour les analyses approfondies planifi\u00e9es o\u00f9 la pr\u00e9cision compte plus que la vitesse.<\/li>\n<li><strong>GitHub push protection et le programme partenaire ajoutent une d\u00e9fense au niveau de la plateforme<\/strong> qui fonctionne sans aucune configuration dans vos pipelines CI\/CD.<\/li>\n<li><strong>Les r\u00e8gles de d\u00e9tection personnalis\u00e9es sont essentielles<\/strong> pour intercepter les secrets sp\u00e9cifiques \u00e0 l&rsquo;organisation que les outils standards manqueront. Investissez du temps dans l&rsquo;\u00e9criture de r\u00e8gles pour vos formats de cl\u00e9s internes.<\/li>\n<li><strong>La d\u00e9fense en profondeur est la seule strat\u00e9gie fiable.<\/strong> Aucun outil ou couche unique ne d\u00e9tecte tout. Combinez pre-commit, analyse dans le pipeline, push protection, analyses planifi\u00e9es et surveillance runtime pour une couverture compl\u00e8te.<\/li>\n<\/ul>\n<h2>Prochaines \u00c9tapes<\/h2>\n<p>Maintenant que vous savez d\u00e9tecter et pr\u00e9venir les fuites de secrets, l&rsquo;\u00e9tape suivante est d&rsquo;\u00e9liminer compl\u00e8tement les secrets cod\u00e9s en dur en adoptant une gestion appropri\u00e9e des secrets :<\/p>\n<ul>\n<li><a href=\"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/secrets-management-ci-cd-pipelines-patterns-vault-2\/\">Gestion des Secrets dans les Pipelines CI\/CD<\/a> \u2014 Apprenez \u00e0 utiliser HashiCorp Vault, AWS Secrets Manager et les magasins de secrets natifs CI\/CD pour injecter des secrets \u00e0 l&rsquo;ex\u00e9cution sans jamais les stocker dans le code.<\/li>\n<li><a href=\"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/short-lived-credentials-workload-identity-federation-ci-cd\/\">Identifiants \u00c9ph\u00e9m\u00e8res et Workload Identity Federation<\/a> \u2014 \u00c9liminez compl\u00e8tement les secrets \u00e0 longue dur\u00e9e de vie en utilisant la f\u00e9d\u00e9ration d&rsquo;identit\u00e9 de charge de travail bas\u00e9e sur OIDC pour authentifier les pipelines aupr\u00e8s des fournisseurs cloud sans aucun identifiant stock\u00e9.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Vue d&rsquo;ensemble Les fuites de secrets dans les pipelines CI\/CD sont la cause num\u00e9ro un de compromission des pipelines. Les identifiants expos\u00e9s \u2014 cl\u00e9s API, mots de passe de bases de donn\u00e9es, jetons d&rsquo;acc\u00e8s cloud \u2014 offrent aux attaquants un acc\u00e8s direct aux syst\u00e8mes de production. Selon le rapport 2025 State of Secrets Sprawl de &#8230; <a title=\"Lab : D\u00e9tection et Pr\u00e9vention des Fuites de Secrets dans les Pipelines CI\/CD\" class=\"read-more\" href=\"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/lab-detecting-preventing-secret-leaks-ci-cd-pipelines\/\" aria-label=\"En savoir plus sur Lab : D\u00e9tection et Pr\u00e9vention des Fuites de Secrets dans les Pipelines CI\/CD\">Lire la suite<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49,51],"tags":[],"post_folder":[],"class_list":["post-520","post","type-post","status-publish","format-standard","hentry","category-ci-cd-security","category-pipeline-hardening"],"_links":{"self":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/520","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/comments?post=520"}],"version-history":[{"count":2,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/520\/revisions"}],"predecessor-version":[{"id":576,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/520\/revisions\/576"}],"wp:attachment":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/media?parent=520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/categories?post=520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/tags?post=520"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/post_folder?post=520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}