Aller au contenu principal

Intégration GitHub Actions

GitGuardian Scout (ggscout) peut inventorier les secrets stockés dans GitHub Actions — au niveau organisation, dépôt et environnement — vous permettant de découvrir et surveiller les Non-Human Identities dans votre infrastructure CI/CD GitHub.

Vue d'ensemble

Contrairement aux autres intégrations ggscout, le fetcher GitHub Actions s'exécute à l'intérieur d'un workflow GitHub Actions. Il lit les secrets directement depuis l'environnement du runner, sans nécessiter d'identifiants pour son fonctionnement de base. Pour une visibilité complète, nous recommandons de configurer un token d'API afin d'enrichir chaque secret avec des métadonnées telles que le scope, la propriété et les horodatages.

L'intégration prend en charge à la fois github.com et les instances GitHub Enterprise Server (GHES).

Capacités clés :

  • Inventorier tous les secrets GitHub Actions disponibles pour un workflow (org, repo et environnement)
  • Enrichir avec des métadonnées (scope, visibilité, environnement, propriétaire, horodatages) lorsqu'un token d'API est fourni

Prérequis

Avant de configurer l'intégration GitHub Actions, assurez-vous de disposer de :

  1. Un dépôt GitHub avec GitHub Actions activé (github.com ou GHES)
  2. Un token d'API GitGuardian avec les permissions NHI
  3. (Recommandé) Un token d'API GitHub pour l'enrichissement des métadonnées — voir Enrichissement des métadonnées

Mise en place du workflow

ggscout est intégré comme une étape dans un workflow GitHub Actions. Les secrets sont relativement statiques et ne changent pas à chaque commit, donc nous recommandons de l'exécuter selon une planification nocturne pour éviter de consommer inutilement des minutes de workflow.

Périmètre de déploiement

Les secrets GitHub Actions existent à trois niveaux : organisation, dépôt et environnement. Un seul workflow ggscout peut voir tous les secrets disponibles pour son job, mais les secrets de niveau dépôt et environnement ne sont visibles que depuis le workflow de ce dépôt spécifique.

Pour obtenir une couverture complète :

  1. Déployez sur au moins un dépôt — cela capture tous les secrets de niveau organisation partagés au sein de l'org.
  2. Déployez sur chaque dépôt avec des secrets d'intérêt — les secrets de niveau dépôt et environnement ne sont accessibles que depuis le dépôt où ils sont définis.

Exemples de workflow

Créez un fichier de workflow dédié (par ex. .github/workflows/ggscout-nhi.yml).

name: NHI Inventory with ggscout
on:
schedule:
- cron: '0 2 * * *' # Run nightly at 2:00 AM UTC
workflow_dispatch: # Allow manual runs

jobs:
inventory:
runs-on: ubuntu-latest
container:
image: ghcr.io/gitguardian/ggscout/chainguard-bash:latest
steps:
- name: Create ggscout config
run: |
cat > /tmp/config.toml << 'EOF'
[sources.github-actions]
type = "githubactions"
env = "production"

[gitguardian]
api_token = "${GITGUARDIAN_API_KEY}"
endpoint = "https://api.gitguardian.com/v1"
EOF

- name: Collect secrets with ggscout
env:
GGSCOUT_GITHUB_ACTION_SECRETS: ${{ toJSON(secrets) }}
GGSCOUT_GITHUB_ACTION_CONTEXT: ${{ toJSON(github) }}
GGSCOUT_GITHUB_API_TOKEN: ${{ secrets.GGSCOUT_API_TOKEN }}
GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}
run: ggscout fetch-and-send /tmp/config.toml

Option B : téléchargement du binaire

Si vous préférez ne pas utiliser Docker :

name: NHI Inventory with ggscout
on:
schedule:
- cron: '0 2 * * *' # Run nightly at 2:00 AM UTC
workflow_dispatch: # Allow manual runs

jobs:
inventory:
runs-on: ubuntu-latest
steps:
- name: Download ggscout
run: |
wget https://ggscout-repository.gitguardian.com/ggscout/latest/x86_64-unknown-linux-gnu/ggscout
chmod +x ggscout

- name: Create ggscout config
run: |
cat > /tmp/config.toml << 'EOF'
[sources.github-actions]
type = "githubactions"
env = "production"

[gitguardian]
api_token = "${GITGUARDIAN_API_KEY}"
endpoint = "https://api.gitguardian.com/v1"
EOF

- name: Collect secrets with ggscout
env:
GGSCOUT_GITHUB_ACTION_SECRETS: ${{ toJSON(secrets) }}
GGSCOUT_GITHUB_ACTION_CONTEXT: ${{ toJSON(github) }}
GGSCOUT_GITHUB_API_TOKEN: ${{ secrets.GGSCOUT_API_TOKEN }}
GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}
run: ./ggscout fetch-and-send /tmp/config.toml

Variables d'environnement

Le workflow doit injecter les variables d'environnement suivantes dans l'étape ggscout. Ces variables sont la manière dont ggscout découvre quels secrets existent et d'où ils proviennent — sans elles, ggscout n'a aucune visibilité sur votre environnement GitHub Actions.

VariableDescriptionRequis
GGSCOUT_GITHUB_ACTION_SECRETS${{ toJSON(secrets) }} — objet JSON de tous les secrets disponibles pour le job. C'est l'entrée principale de ggscout pour découvrir les secrets.Oui
GGSCOUT_GITHUB_ACTION_CONTEXT${{ toJSON(github) }} — contexte GitHub fournissant l'identité de la source (URL du serveur, propriétaire du dépôt, nom du dépôt).Oui
GGSCOUT_GITHUB_API_TOKENToken d'API GitHub pour l'enrichissement des métadonnées (voir Enrichissement des métadonnées).Non (recommandé)
GITGUARDIAN_API_KEYToken d'API GitGuardian avec les permissions NHI.Oui

Configuration

La configuration TOML de ggscout pour GitHub Actions est minimale — l'identité de la source (hostname, org, repo) est dérivée automatiquement du contexte du runner GitHub.

Dans les exemples de workflow ci-dessus, la configuration est créée inline pendant l'exécution du workflow. Vous pouvez aussi committer un fichier config.toml dans votre dépôt et le référencer directement (en utilisant actions/checkout pour le rendre disponible) :

[sources.github-actions]
type = "githubactions"
env = "production" # Optional: Environment label
owner = "devops-team@example.com" # Optional: Owner of this source
token = "${GGSCOUT_GITHUB_API_TOKEN}" # Optional: GitHub API token for metadata enrichment

[gitguardian]
api_token = "${GITGUARDIAN_API_KEY}"
endpoint = "https://api.gitguardian.com/v1"

Paramètres de configuration

ParamètreDescriptionRequisExemple
typeDoit être "githubactions"Oui"githubactions"
envLibellé d'environnement pour catégoriser les secretsNon"production"
ownerPropriétaire de cette source (un e-mail, généralement d'un employé ou d'une équipe)Non"devops-team@example.com"
tokenToken d'API GitHub (fallback si la variable d'env. GGSCOUT_GITHUB_API_TOKEN n'est pas définie)Non"ghp_xxxx"

Enrichissement des métadonnées

Par défaut, ggscout inventorie les noms et valeurs des secrets depuis l'environnement du runner. Lorsqu'un token d'API GitHub est fourni (via GGSCOUT_GITHUB_API_TOKEN ou le champ token de la configuration), ggscout appelle aussi l'API REST GitHub pour enrichir chaque secret avec des métadonnées supplémentaires :

  • Horodatages created_at et updated_at
  • Tag scope"org", "repo" ou "env", indiquant où le secret est défini
  • Tag visibility — pour les secrets de niveau org : "all", "private" ou "selected"
  • Tag environment — pour les secrets de niveau environnement : le nom de l'environnement (par ex. "production")
  • Tag owner_email — depuis le profil utilisateur GitHub du propriétaire du dépôt/de l'org

Permissions requises pour le token

Type de tokenPermissionsPérimètre
Fine-grained PATRepository : Secrets : Read + Environments : Read. Organization : Secrets : ReadSecrets repo + environnement + org
Classic PATrepo + admin:orgSecrets repo + environnement + org
GitHub Appsecrets:read + environments:read + organization_secrets:readSecrets repo + environnement + org

L'absence de scopes entraîne des warnings 403 Forbidden dans les logs. Le fetcher continue sans les métadonnées correspondantes (dégradation gracieuse).

Considérations sur les rate limits

Lorsque l'enrichissement des métadonnées est activé, ggscout effectue environ 5 à 10 appels API par exécution (lister les secrets de niveau org, repo et environnement, plus les infos du propriétaire). Les rate limits dépendent du type de token :

Type de tokenRate limit
GITHUB_TOKEN1 000 req/h par dépôt (15 000 pour Enterprise Cloud)
Personal Access Token5 000 req/h partagés sur toutes les utilisations (15 000 pour Enterprise Cloud)
GitHub App5 000–15 000 req/h selon la taille de l'installation

Important : les rate limits des PAT sont partagés sur toutes les utilisations par cet utilisateur. Si plusieurs dépôts exécutent ggscout avec le même PAT en même temps, les appels API combinés peuvent épuiser le quota.

Recommandation : utilisez un token GitHub App ou un PAT de service account dédié plutôt qu'un PAT personnel. Les PAT personnels partagent leur quota de rate limit avec toute autre activité API de cet utilisateur, ce qui peut conduire à un throttling inattendu. Un token GitHub App fournit un pool de rate limit dédié par installation et évite les identifiants à longue durée de vie.

GitHub Enterprise Server

L'intégration prend automatiquement en charge les instances GHES. Le hostname et l'URL de l'API sont dérivés du contexte github fourni par le runner — aucune configuration supplémentaire n'est nécessaire.

Le champ server_url du contexte GitHub est analysé pour déterminer le hostname (par ex. github.example.com au lieu de github.com), et api_url est utilisé pour les appels REST API lorsque l'enrichissement des métadonnées est activé.

Données collectées

L'intégration GitHub Actions collecte les données suivantes :

  • Tous les secrets définis par l'utilisateur disponibles pour le job du workflow au runtime, y compris les secrets de niveau org, repo et environnement
  • Métadonnées des secrets (lorsqu'un token d'API est fourni) : horodatages, scope, visibilité, environnement et propriétaire

Exclu : GITHUB_TOKEN — c'est un token éphémère automatiquement généré par GitHub pour chaque exécution de workflow. Il expire à la fin du job ou après 24 heures, et n'est pas une NHI gérée par l'utilisateur.

Note sur le shadowing des secrets d'environnement : les environnements GitHub Actions (par ex. production, staging) peuvent définir des secrets qui surchargent les secrets repo ou org du même nom. Le contexte secrets présente tous les scopes comme un objet plat, donc l'origine n'est pas visible depuis le workflow. Lorsque l'enrichissement des métadonnées est activé, ggscout interroge tous les environnements et applique la priorité environnement > repo > org pour attribuer correctement les tags scope et environment.

Résolution de problèmes

Aucune métadonnée n'apparaît

  • Vérifiez que GGSCOUT_GITHUB_API_TOKEN est défini (ou que token est configuré dans le fichier TOML)
  • Vérifiez que le token a les permissions requises (voir Permissions requises pour le token)
  • Recherchez des warnings 403 Forbidden dans les logs du workflow — cela indique des scopes manquants

Inventaire vide

  • Assurez-vous que GGSCOUT_GITHUB_ACTION_SECRETS est défini sur ${{ toJSON(secrets) }} dans l'étape du workflow
  • Assurez-vous que GGSCOUT_GITHUB_ACTION_CONTEXT est défini sur ${{ toJSON(github) }}
  • Vérifiez que le dépôt a des secrets GitHub Actions configurés

Mode debug

Activez le logging verbose pour résoudre les problèmes :

- name: Collect secrets with ggscout (debug)
env:
GGSCOUT_GITHUB_ACTION_SECRETS: ${{ toJSON(secrets) }}
GGSCOUT_GITHUB_ACTION_CONTEXT: ${{ toJSON(github) }}
RUST_LOG: debug
run: ggscout fetch /tmp/config.toml --verbose -o inventory.json

- name: View inventory.json
run: cat inventory.json | python3 -m json.tool