Intégration GitHub Actions
GitGuardian Scout (ggscout) peut inventorier les secrets stockés dans GitHub Actions — au niveau de l'organisation, du dépôt et de l'environnement — ce qui vous permet de découvrir et de surveiller les Non-Human Identities à travers 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, ne nécessitant aucun identifiant pour un 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 la portée, la propriété et les horodatages.
L'intégration prend en charge à la fois les instances github.com et GitHub Enterprise Server (GHES).
Principales fonctionnalités :
- Inventorier tous les secrets GitHub Actions disponibles pour un workflow (au niveau de l'organisation, du dépôt et de l'environnement)
- Enrichir avec des métadonnées (portée, 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
Configuration 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, nous recommandons donc de l'exécuter selon une planification nocturne afin d'éviter des minutes de workflow inutiles.
Portée du 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 au niveau du dépôt et de l'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 au niveau de l'organisation partagés dans l'organisation.
- Déployez sur chaque dépôt contenant des secrets d'intérêt — les secrets au niveau du dépôt et de l'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 exemple, .github/workflows/ggscout-nhi.yml).
Option A : image Docker (recommandée)
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 sur l'étape ggscout. Ces variables permettent à ggscout de découvrir 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 (nom d'hôte, organisation, dépôt) est dérivée automatiquement du contexte du runner GitHub.
Dans les exemples de workflow ci-dessus, la configuration est créée en ligne 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 | Environnement par défaut des secrets de cette source. GitGuardian infère un environnement par secret et se rabat sur cette valeur | Non | "production" |
owner | Propriétaire de cette source (un e-mail, généralement celui d'un employé ou d'une équipe) | Non | "devops-team@example.com" |
token | Token d'API GitHub (solution de repli si la variable d'environnement GGSCOUT_GITHUB_API_TOKEN n'est pas définie) | Non | "ghp_xxxx" |
Pour les secrets au niveau de l'environnement, GitGuardian lit le tag environment collecté par l'enrichissement des métadonnées comme l'environnement du secret, et utilise le env au niveau de la source pour les autres.
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 de configuration token), ggscout appelle également l'API REST de GitHub pour enrichir chaque secret avec des métadonnées supplémentaires :
- Les horodatages
created_atetupdated_at - Le tag
scope—"org","repo"ou"env", indiquant où le secret est défini - Le tag
visibility— pour les secrets au niveau de l'organisation :"all","private"ou"selected" - Le tag
environment— pour les secrets au niveau de l'environnement : le nom de l'environnement (par exemple,"production") - Le tag
owner_email— issu du profil utilisateur GitHub du propriétaire du dépôt/de l'organisation
Permissions de token requises
| Type de token | Permissions | Portée |
|---|---|---|
| Fine-grained PAT | Dépôt : Secrets: Read + Environments: Read. Organisation : Secrets: Read | Secrets de dépôt + environnement + organisation |
| Classic PAT | repo + admin:org | Secrets de dépôt + environnement + organisation |
| GitHub App | secrets:read + environments:read + organization_secrets:read | Secrets de dépôt + environnement + organisation |
Les portées manquantes entraînent des avertissements 403 Forbidden dans les logs. Le fetcher continue sans les métadonnées correspondantes (dégradation progressive).
Considérations relatives aux limites de débit
Lorsque l'enrichissement des métadonnées est activé, ggscout effectue environ 5 à 10 appels d'API par exécution (listage des secrets au niveau de l'organisation, du dépôt et de l'environnement, plus les informations sur le propriétaire). Les limites de débit dépendent du type de token :
| Type de token | Limite de débit |
|---|---|
| GITHUB_TOKEN | 1 000 req/h par dépôt (15 000 pour Enterprise Cloud) |
| Personal Access Token | 5 000 req/h partagées entre toutes les utilisations (15 000 pour Enterprise Cloud) |
| GitHub App | 5 000 à 15 000 req/h selon la taille de l'installation |
Important : les limites de débit des PAT sont partagées entre toutes les utilisations par cet utilisateur. Si plusieurs dépôts exécutent ggscout avec le même PAT simultanément, les appels d'API combinés peuvent épuiser le quota.
Recommandation : utilisez un token GitHub App ou un PAT de compte de service dédié plutôt qu'un PAT personnel. Les PAT personnels partagent leur quota de limite de débit avec toute autre activité d'API de cet utilisateur, ce qui peut entraîner une limitation inattendue. Un token GitHub App fournit un pool de limite de débit 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 nom d'hôte 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 nom d'hôte (par exemple, github.example.com au lieu de github.com), et api_url est utilisé pour les appels à l'API REST 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 moment de l'exécution, y compris les secrets au niveau de l'organisation, du dépôt et de l'environnement
- Les métadonnées des secrets (lorsqu'un token d'API est fourni) : horodatages, portée, visibilité, environnement et propriétaire
Exclu : GITHUB_TOKEN — il s'agit d'un token éphémère généré automatiquement 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 masquage des secrets d'environnement : les environnements GitHub Actions (par exemple, production, staging) peuvent définir des secrets qui remplacent les secrets de dépôt ou d'organisation portant le même nom. Le contexte secrets présente toutes les portées comme un objet plat, de sorte que 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 l'ordre de priorité environnement > dépôt > organisation pour attribuer correctement les tags scope et environment.
Dépannage
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 dispose des permissions requises (voir Permissions de token requises)
- Recherchez les avertissements
403 Forbiddendans les logs du workflow — cela indique des portées manquantes
Inventaire vide
- Assurez-vous que
GGSCOUT_GITHUB_ACTION_SECRETSest défini à${{ toJSON(secrets) }}dans l'étape du workflow - Assurez-vous que
GGSCOUT_GITHUB_ACTION_CONTEXTest défini à${{ toJSON(github) }} - Vérifiez que le dépôt a des secrets GitHub Actions configurés
Mode débogage
Activez la journalisation détaillée 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