Aller au contenu principal

Intégration HashiCorp Vault

GGScout prend en charge l'intégration avec HashiCorp Vault pour collecter et surveiller vos secrets, y compris Vault Community Edition et Vault Enterprise (self-hosted et HashiCorp Cloud Dedicated). Ce guide vous aidera à mettre en place et configurer l'intégration.

Fonctionnalités prises en charge​

Disponibles sur toutes les éditions (Community et Enterprise) :

  • Moteurs de secrets KV1 et KV2
  • Collecte de plusieurs versions de secrets
  • Filtrage basé sur les chemins
  • Authentification par token
  • Type de montage explicite facultatif (kv-v1/kv-v2) pour ignorer la détection automatique sys/*

Disponibles uniquement sur Vault Enterprise et HashiCorp Cloud Dedicated (HCD) :

  • Prise en charge des namespaces

Prise en charge de HashiCorp Cloud Dedicated​

GGScout prend entièrement en charge les environnements HashiCorp Cloud Dedicated (HCD). Lorsque vous utilisez HCD, les namespaces sont automatiquement inclus dans le resource_id exporté, suivant le modèle de l'API Vault décrit dans la documentation HashiCorp.

Filtrage par namespace​

Restreindre l'accès aux namespaces (Enterprise et HCD uniquement)​

Les namespaces sont une fonctionnalité de Vault Enterprise et HCD. Avec ces éditions, vous pouvez limiter les namespaces auxquels ggscout accède à l'aide du paramètre de configuration namespaces :

[sources.vault]
type = "hashicorpvault"
vault_address = "${VAULT_ADDR}"
fetch_all_versions = true
namespaces = ["admin", "prod", "shared"] # Only fetch from these namespaces
info

Si le paramètre namespaces n'est pas spécifié, ggscout récupérera les secrets de tous les namespaces accessibles. Utilisez ce paramètre pour limiter la portée de la collecte de secrets et améliorer les performances.

Filtrage au niveau des ressources​

Vous pouvez également filtrer les secrets par namespace directement dans vos modèles d'inclusion/exclusion. Le namespace devient une partie du chemin de la ressource, ce qui permet un filtrage précis :

# Include all secrets from the 'admin' namespace, 'kv' mount, under 'my_app' path
[[sources.vault.include]]
resource_ids = ["admin/kv/my_app/*"]

# Include secrets from multiple namespaces
[[sources.vault.include]]
resource_ids = ["admin/kv/*", "dev/secrets/*", "prod/database/*"]

# Exclude test secrets from all namespaces
[[sources.vault.exclude]]
resource_ids = ["*/test/*", "*/temp/*"]

Le filtrage fonctionne de manière transparente avec la structure de namespace, où le format du resource_id suit : namespace/mount/path

Configuration​

Pour configurer GGScout afin qu'il fonctionne avec HashiCorp Vault, ajoutez la configuration suivante à votre fichier ggscout.toml :

Authentification par token​

[sources.vault]
type = "hashicorpvault"
vault_address = "${VAULT_ADDR}"
fetch_all_versions = true
mode = "read"
env = "production"
owner = "devops-team@example.com"

auth.auth_mode = "token"
auth.token = "${VAULT_TOKEN}"

# Optional: Limit to specific namespaces (Vault Enterprise and HCD only)
namespaces = ["admin", "prod", "shared"]

# Standard filtering (works on all editions including Vault Community Edition)
[[sources.vault.include]]
resource_ids = ["app/*", "database/*", "api-key"]

# Namespace-aware filtering (Vault Enterprise and HCD only)
[[sources.vault.include]]
resource_ids = ["admin/kv/my_app/*", "prod/secrets/database/*"]

[[sources.vault.exclude]]
resource_ids = ["*/test/*", "*/temp/*", "dev/old-secret"]

Configuration HashiCorp Cloud Dedicated​

Pour les environnements HashiCorp Cloud Dedicated, la configuration est identique, mais le filtrage fonctionne automatiquement avec les namespaces :

[sources.vault_hcd]
type = "hashicorpvault"
vault_address = "${HCD_VAULT_ADDR}"
fetch_all_versions = true
mode = "read"
env = "production"
owner = "devops-team@example.com"

auth.auth_mode = "token"
auth.token = "${HCD_VAULT_TOKEN}"

# Optional: Limit to specific namespaces
namespaces = ["admin", "prod", "shared"]

# Namespace-specific filtering
[[sources.vault_hcd.include]]
resource_ids = [
"admin/kv/my_app/*", # All secrets in admin namespace, kv mount, my_app path
"prod/database/credentials/*", # Database credentials in prod namespace
"shared/api-keys/*" # Shared API keys across teams
]

[[sources.vault_hcd.exclude]]
resource_ids = [
"*/test/*", # Exclude test secrets from all namespaces
"dev/temp/*", # Exclude temporary secrets in dev namespace
"*/legacy/*" # Exclude legacy secrets from all namespaces
]

Authentification Kubernetes​

[sources.vault]
type = "hashicorpvault"
vault_address = "${VAULT_ADDR}"
fetch_all_versions = true
mode = "read"
env = "production"
owner = "devops-team@example.com"

auth.auth_mode = "k8s"
auth.k8s.service_account = "${KUBERNETES_SERVICE_ACCOUNT}"
auth.k8s.namespace = "${KUBERNETES_NAMESPACE}"
auth.k8s.role = "${KUBERNETES_ROLE}"

[[sources.vault.include]]
resource_ids = ["app/*", "database/*", "api-key"]

[[sources.vault.exclude]]
resource_ids = ["test/*", "temp/*", "old-secret"]

Paramètres de configuration​

ParamètreDescriptionRequisValeur par défaut
typeDoit être défini sur "hashicorpvault"Oui
vault_addressL'adresse de votre serveur VaultOui
fetch_all_versionsIndique s'il faut collecter toutes les versions des secretsOui
namespacesListe des namespaces Vault à récupérer (Vault Enterprise et HCD uniquement). Si non spécifié, récupère depuis tous les namespaces accessiblesNonTous les namespaces accessibles
mount_typeType de moteur de secrets du ou des montages épinglés : "kv-v1" ou "kv-v2". Lorsqu'il est défini, ggscout utilise le type déclaré et ignore la détection de montage sys/*. Ne s'applique que lorsque include/path épingle le ou les montages.NonDétecté automatiquement
auth.auth_modeMode d'authentification (ex. : "token", "k8s")Oui
modeMode d'intégration (l'un de : "read", "write", "read/write")Non"read"
envEnvironnement par défaut des secrets de cette source. GitGuardian déduit un environnement par secret et se rabat sur cette valeurNon
ownerPropriétaire de cette source (un e-mail, généralement d'un employé ou d'une équipe)Non
[[sources.<name>.include]]Table de modèles de resource_id à inclure (voir ci-dessous)Non
[[sources.<name>.exclude]]Table de modèles de resource_id à exclure (voir ci-dessous)Non

GitGuardian déduit l'environnement de chaque secret Vault d'abord à partir de son chemin (namespace, montage KV et dossiers, lus comme des composants entiers, le plus profond l'emporte), puis à partir des clés custom_metadata de KV v2 telles que env ou environment, et n'utilise env que lorsque ni l'un ni l'autre n'en nomme un.

Avec des paramètres supplémentaires selon le mode d'authentification choisi :

Pour l'authentification par token :

ParamètreDescriptionRequisValeur par défaut
auth.tokenLe token d'authentification VaultOui

Pour l'authentification Kubernetes :

ParamètreDescriptionRequisValeur par défaut
auth.k8s.service_accountLe compte de service KubernetesOui
auth.k8s.namespaceLe namespace KubernetesOui
auth.k8s.roleLe rôle KubernetesOui

Variables d'environnement​

  • VAULT_ADDR : L'adresse de votre serveur Vault (ex. : http://localhost:8200)

Pour l'authentification par token :

  • VAULT_TOKEN : Votre token d'authentification Vault

Pour l'authentification Kubernetes :

  • KUBERNETES_SERVICE_ACCOUNT : Le compte de service Kubernetes
  • KUBERNETES_NAMESPACE : Le namespace Kubernetes
  • KUBERNETES_ROLE : Le rôle Kubernetes

Ignorer la détection de montage avec mount_type​

ggscout détecte automatiquement la version du moteur KV de chaque montage, donc ceci est facultatif — voir Politiques Vault requises ci-dessous pour comprendre pourquoi aucun accès à sys/* n'est nécessaire. Déclarer le type avec mount_type ignore entièrement la détection, ce qui est utile lorsque votre token se voit refuser l'accès à sys/* ou lorsque vous souhaitez éviter des appels supplémentaires à chaque exécution planifiée :

[sources.vault]
type = "hashicorpvault"
vault_address = "${VAULT_ADDR}"
mount_type = "kv-v1" # or "kv-v2"

auth.auth_mode = "token"
auth.token = "${VAULT_TOKEN}"

# mount_type only applies when an include pattern (or the deprecated `path`) pins the mount:
[[sources.vault.include]]
resource_ids = ["secret/app/*"]
info

mount_type ne prend effet que lorsqu'un montage est épinglé par un modèle include (ou le path déprécié). Si aucun montage n'est épinglé, ggscout se rabat sur la détection automatique. La valeur s'applique à chaque montage épinglé par les filtres, utilisez-la donc lorsque ces montages partagent la même version de moteur.

Politiques Vault requises​

GGScout a besoin de l'autorisation de lire les secrets que vous souhaitez inventorier. Il détecte automatiquement le type et la version du moteur KV (en utilisant la même recherche par chemin que la CLI vault kv), de sorte que l'octroi de sys/mounts n'est pas requis.

L'étendue nécessaire de la politique dépend de si vous collectez un montage entier ou si vous vous limitez à un path spécifique. Pour les modes d'écriture (mode = "write" ou "read/write"), accordez également create et update sur les chemins data.

Collecter un montage entier​

L'option la plus simple — accordez l'accès à l'ensemble du montage :

# KV2
path "secret/metadata/*" { capabilities = ["read", "list"] }
path "secret/data/*" { capabilities = ["read"] }

# KV1
path "secret/*" { capabilities = ["read", "list"] }

Se limiter à un chemin spécifique (moindre privilège)​

Lorsque vous définissez un path (ou un filtre d'inclusion), accordez l'accès uniquement à ce chemin. GGScout le collecte, que le chemin soit un dossier de secrets ou un secret unique — aucun accès au reste du montage (ou à sys/mounts) n'est nécessaire.

Un dossier — chaque secret sous un chemin, ex. path = "secret/app/team" :

# KV2
path "secret/metadata/app/team" { capabilities = ["list"] }
path "secret/metadata/app/team/*" { capabilities = ["read", "list"] }
path "secret/data/app/team/*" { capabilities = ["read"] }

Un secret unique, ex. path = "secret/app/db-creds" :

# KV2
path "secret/metadata/app/db-creds" { capabilities = ["read"] }
path "secret/data/app/db-creds" { capabilities = ["read"] }

Pour KV1, supprimez les segments data/ et metadata/ (ex. path "secret/app/team/*").

Pour HashiCorp Cloud Dedicated et Enterprise (avec namespaces)​

Lorsque vous utilisez HCD ou Vault Enterprise avec des namespaces, les politiques sont limitées au namespace où elles sont créées. Chaque namespace possède son propre espace de politiques, et vous créez des politiques au sein de namespaces spécifiques plutôt que d'utiliser des caractères génériques pour correspondre à plusieurs namespaces.

Pour les politiques spécifiques aux namespaces, vous créeriez des politiques au sein de chaque namespace :

# Policy created within the 'admin' namespace for KV2 secrets
path "kv/data/*" {
capabilities = ["read", "list"]
}

path "kv/metadata/*" {
capabilities = ["read", "list"]
}

# Policy for specific paths within a namespace using the + wildcard
path "kv/data/my_app/+/config" {
capabilities = ["read", "list"]
}

path "kv/metadata/my_app/+/config" {
capabilities = ["read", "list"]
}
info

Lorsque vous travaillez avec des namespaces, les politiques sont créées et gérées au sein de la portée de chaque namespace. Le caractère générique + peut être utilisé au sein des segments de chemin comme documenté dans la documentation HashiCorp Vault Policies, mais les caractères génériques de politique inter-namespaces ne sont pas pris en charge. Pour plus d'informations sur les namespaces, consultez la documentation HashiCorp Vault Namespace.

Bonnes pratiques​

  1. Utilisez des variables d'environnement pour les valeurs sensibles comme auth.token
  2. Tirez parti du filtrage par namespace dans les environnements Vault Enterprise et HCD pour contrôler précisément quels secrets sont collectés
  3. Envisagez d'utiliser des restrictions de chemin pour limiter la portée de la collecte de secrets
  4. Activez fetch_all_versions pour suivre les modifications de vos secrets au fil du temps
  5. Utilisez un compte de service dédié avec les permissions minimales requises
  6. Pour les environnements HCD, profitez de l'inclusion automatique du namespace dans les resource_ids pour un filtrage granulaire
  7. Utilisez des modèles de caractères génériques comme */test/* pour exclure les secrets de test dans tous les namespaces