Skip to main content

HashiCorp Vault Integration

GGScout supports integration with HashiCorp Vault to collect and monitor your secrets. This guide will help you set up and configure the integration.

Supported Features

  • KV1 and KV2 secret engines
  • Multiple secret versions collection
  • Path-based filtering
  • Token-based authentication
  • HashiCorp Vault Enterprise namespaces
  • HashiCorp Cloud Dedicated (HCD) support

HashiCorp Cloud Dedicated Support

GGScout fully supports HashiCorp Cloud Dedicated (HCD) environments. When using HCD, namespaces are automatically included as part of the exported resource_id, following the Vault API pattern described in the HashiCorp documentation.

Namespace Filtering

With HCD and Vault Enterprise, you can filter secrets by namespace directly in your include/exclude patterns. The namespace becomes part of the resource path, allowing for precise filtering:

# 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/*"]

The filtering works seamlessly with the namespace structure, where the resource_id format follows: namespace/mount/path

Configuration

To configure GGScout to work with HashiCorp Vault, add the following configuration to your ggscout.toml file:

Token-based Authentication

[sources.vault]
type = "hashicorpvault"
vault_address = "${VAULT_ADDR}"
fetch_all_versions = true
path = "secret/"
mode = "read"
env = "production"

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

# Standard filtering (self-hosted Vault)
[[sources.vault.include]]
resource_ids = ["app/*", "database/*", "api-key"]

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

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

HashiCorp Cloud Dedicated Configuration

For HashiCorp Cloud Dedicated environments, the configuration is identical, but the filtering automatically works with namespaces:

[sources.vault_hcd]
type = "hashicorpvault"
vault_address = "${HCD_VAULT_ADDR}"
fetch_all_versions = true
mode = "read"
env = "production"

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

# 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
]

Kubernetes Authentication

[sources.vault]
type = "hashicorpvault"
vault_address = "${VAULT_ADDR}"
fetch_all_versions = true
path = "secret/"
mode = "read"
env = "production"

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"]

Configuration Parameters

ParameterDescriptionRequiredDefault Value
typeMust be set to "hashicorpvault"Yes
vault_addressThe address of your Vault serverYes
fetch_all_versionsWhether to collect all versions of secretsYes
pathOptional path to restrict secret collectionNo
auth.auth_modeAuthentication mode (e.g., "token", "k8s")Yes
modeIntegration mode (one of: "read", "write", "read/write")No"read"
envEnvironment label for categorizing secrets (e.g., "production", "staging", "development")No
[[sources.<name>.include]]Table of resource_id patterns to include (see below)No
[[sources.<name>.exclude]]Table of resource_id patterns to exclude (see below)No

With additional parameters depending on the chosen authentication mode:

For Token-based Authentication:

ParameterDescriptionRequiredDefault Value
auth.tokenThe Vault authentication tokenYes

For Kubernetes Authentication:

ParameterDescriptionRequiredDefault Value
auth.k8s.service_accountThe Kubernetes service accountYes
auth.k8s.namespaceThe Kubernetes namespaceYes
auth.k8s.roleThe Kubernetes roleYes

Environment Variables

  • VAULT_ADDR: The address of your Vault server (e.g., http://localhost:8200)

For Token-based Authentication:

  • VAULT_TOKEN: Your Vault authentication token

For Kubernetes Authentication:

  • KUBERNETES_SERVICE_ACCOUNT: The Kubernetes service account
  • KUBERNETES_NAMESPACE: The Kubernetes namespace
  • KUBERNETES_ROLE: The Kubernetes role

Required Vault Policies

GGScout requires specific permissions in HashiCorp Vault to collect secrets. The token used for authentication must have the following permissions:

For KV2 Secret Engine

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

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

These policies allow GGScout to:

  1. List all secrets in the specified path(s)
  2. Read the content of each secret
  3. Access metadata about the secrets

For KV1 Secret Engine

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

This policy allows GGScout to:

  1. List all secrets in the specified path(s)
  2. Read the content of each secret

For HashiCorp Cloud Dedicated & Enterprise (with Namespaces)

When using HCD or Vault Enterprise with namespaces, policies are scoped to the namespace where they are created. Each namespace has its own policy space, and you create policies within specific namespaces rather than using wildcards to match across namespaces.

For namespace-specific policies, you would create policies within each 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

When working with namespaces, policies are created and managed within each namespace's scope. The + wildcard character can be used within path segments as documented in the HashiCorp Vault Policies documentation, but cross-namespace policy wildcards are not supported. For more information about namespaces, see the HashiCorp Vault Namespace documentation.

Best Practices

  1. Use environment variables for sensitive values like auth.token
  2. Leverage namespace filtering in HCD/Enterprise environments to precisely control which secrets are collected
  3. Consider using path restrictions to limit the scope of secret collection
  4. Enable fetch_all_versions to track changes in your secrets over time
  5. Use a dedicated service account with minimal required permissions
  6. For HCD environments, take advantage of the automatic namespace inclusion in resource_ids for fine-grained filtering
  7. Use wildcard patterns like */test/* to exclude test secrets across all namespaces