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 :
- Un dépôt GitHub avec GitHub Actions activé (github.com ou GHES)
- Un token d'API GitGuardian avec les permissions NHI
- (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 :
- Déployez sur au moins un dépôt — cela capture tous les secrets de niveau organisation partagés au sein de l'org.
- 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).
Option A : image Docker (recommandé)
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.
| Variable | Description | Requis |
|---|---|---|
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_TOKEN | Token d'API GitHub pour l'enrichissement des métadonnées (voir Enrichissement des métadonnées). | Non (recommandé) |
GITGUARDIAN_API_KEY | Token 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ètre | Description | Requis | Exemple |
|---|---|---|---|
type | Doit être "githubactions" | Oui | "githubactions" |
env | Libellé d'environnement pour catégoriser les secrets | Non | "production" |
owner | Propriétaire de cette source (un e-mail, généralement d'un employé ou d'une équipe) | Non | "devops-team@example.com" |
token | Token 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_atetupdated_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 token | Permissions | Périmètre |
|---|---|---|
| Fine-grained PAT | Repository : Secrets : Read + Environments : Read. Organization : Secrets : Read | Secrets repo + environnement + org |
| Classic PAT | repo + admin:org | Secrets repo + environnement + org |
| GitHub App | secrets:read + environments:read + organization_secrets:read | Secrets 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 token | Rate limit |
|---|---|
| GITHUB_TOKEN | 1 000 req/h par dépôt (15 000 pour Enterprise Cloud) |
| Personal Access Token | 5 000 req/h partagés sur toutes les utilisations (15 000 pour Enterprise Cloud) |
| GitHub App | 5 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_TOKENest défini (ou quetokenest configuré dans le fichier TOML) - Vérifiez que le token a les permissions requises (voir Permissions requises pour le token)
- Recherchez des warnings
403 Forbiddendans les logs du workflow — cela indique des scopes manquants
Inventaire vide
- Assurez-vous que
GGSCOUT_GITHUB_ACTION_SECRETSest défini sur${{ toJSON(secrets) }}dans l'étape du workflow - Assurez-vous que
GGSCOUT_GITHUB_ACTION_CONTEXTest 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