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 le chemin
  • Authentification par token
  • Type de mount explicite facultatif (kv-v1/kv-v2) pour éviter l'auto-détection via 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). Lors de l'utilisation de HCD, les namespaces sont automatiquement inclus dans le resource_id exporté, en suivant le schéma d'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 en utilisant le 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 motifs d'inclusion/exclusion. Le namespace devient partie intégrante du chemin de la ressource, permettant 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 des namespaces, 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 à "hashicorpvault"Oui
vault_addressL'adresse de votre serveur VaultOui
fetch_all_versionsIndique si toutes les versions des secrets doivent être collectéesOui
namespacesListe des namespaces Vault à interroger (Vault Enterprise et HCD uniquement). Si non spécifié, récupère depuis tous les namespaces accessiblesNonTous les namespaces accessibles
mount_typeType du moteur de secrets pour le(s) mount(s) épinglé(s) : "kv-v1" ou "kv-v2". Lorsqu'il est défini, ggscout utilise le type déclaré et évite la détection de mount via sys/*. Ne s'applique que lorsque include/path épingle le(s) mount(s).NonAuto-détecté
auth.auth_modeMode d'authentification (par exemple, "token", "k8s")Oui
modeMode d'intégration (l'un des : "read", "write", "read/write")Non"read"
envÉtiquette d'environnement pour catégoriser les secrets (par exemple, "production", "staging", "development")Non
ownerPropriétaire de cette source (un e-mail, généralement d'un employé ou d'une équipe)Non
[[sources.<name>.include]]Table des motifs de resource_id à inclure (voir ci-dessous)Non
[[sources.<name>.exclude]]Table des motifs de resource_id à exclure (voir ci-dessous)Non

Avec des paramètres supplémentaires en fonction du 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 service account KubernetesOui
auth.k8s.namespaceLe namespace KubernetesOui
auth.k8s.roleLe rôle KubernetesOui

Variables d'environnement

  • VAULT_ADDR : L'adresse de votre serveur Vault (par exemple, http://localhost:8200)

Pour l'authentification par token :

  • VAULT_TOKEN : Votre token d'authentification Vault

Pour l'authentification Kubernetes :

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

Éviter la détection de mount avec mount_type

ggscout auto-détecte la version du moteur KV de chaque mount, donc ce paramètre 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 évite entièrement la détection, ce qui est utile lorsque votre token n'a pas 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 mount est épinglé par un motif include (ou l'ancien paramètre path). Si aucun mount n'est épinglé, ggscout revient à l'auto-détection. La valeur s'applique à tous les mounts que les filtres épinglent, utilisez-la donc lorsque ces mounts partagent la même version du moteur.

Politiques Vault requises

GGScout a besoin de la permission 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), donc il n'est pas nécessaire d'accorder l'accès à sys/mounts.

L'étendue de la politique nécessaire dépend de si vous collectez un mount entier ou si 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 mount entier

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

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

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

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 mount (ou à sys/mounts) n'est nécessaire.

Un dossier — chaque secret sous un chemin, par exemple 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, par exemple 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/ (par exemple path "secret/app/team/*").

Pour HashiCorp Cloud Dedicated & Enterprise (avec namespaces)

Lors de l'utilisation de HCD ou Vault Enterprise avec des namespaces, les politiques sont limitées au namespace dans lequel elles sont créées. Chaque namespace a son propre espace de politiques, et vous créez des politiques dans des namespaces spécifiques plutôt que d'utiliser des jokers pour correspondre à travers les namespaces.

Pour des politiques spécifiques à un namespace, vous créeriez des politiques dans 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 dans le périmètre de chaque namespace. Le caractère joker + peut être utilisé au sein des segments de chemin comme documenté dans la documentation des politiques HashiCorp Vault, mais les jokers de politique inter-namespaces ne sont pas pris en charge. Pour plus d'informations sur les namespaces, consultez la documentation des namespaces HashiCorp Vault.

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 service account dédié avec les permissions minimales requises
  6. Pour les environnements HCD, tirez parti de l'inclusion automatique des namespaces dans les resource_ids pour un filtrage précis
  7. Utilisez des motifs génériques comme */test/* pour exclure les secrets de test dans tous les namespaces