HashiCorp Vault
The vault package provides a fig.SecretProvider backed by HashiCorp Vault's KV v2 secrets engine.
Installation
go get github.com/zoobzio/fig/vault
Quick Start
import (
"log"
"github.com/zoobzio/fig"
"github.com/zoobzio/fig/vault"
)
type Config struct {
DBPassword string `secret:"database/credentials:password"`
APIKey string `secret:"services/api:key"`
}
func main() {
provider, err := vault.New()
if err != nil {
log.Fatal(err)
}
var cfg Config
if err := fig.Load(&cfg, provider); err != nil {
log.Fatal(err)
}
}
Configuration
Environment Variables
The provider uses Vault's standard environment variables:
| Variable | Description | Required |
|---|---|---|
VAULT_ADDR | Vault server address | Yes |
VAULT_TOKEN | Authentication token | No (can be empty for unauthenticated access) |
VAULT_CACERT | CA certificate path for TLS | No (uses system CAs) |
Mount Path
By default, the provider uses the secret mount. Configure a different mount:
provider, err := vault.New(vault.WithMount("kv"))
Key Format
Keys follow the format path/to/secret:field:
// Vault path: secret/data/database/credentials
// Field: password
Password string `secret:"database/credentials:password"`
If no field is specified, value is used:
// Vault path: secret/data/api-key
// Field: value
APIKey string `secret:"api-key"`
Example Vault Data
vault kv put secret/database/credentials \
username=admin \
password=supersecret
vault kv put secret/api-key \
value=sk_live_12345
Corresponding config:
type Config struct {
DBUser string `secret:"database/credentials:username"`
DBPassword string `secret:"database/credentials:password"`
APIKey string `secret:"api-key"` // uses "value" field
}
API Reference
New
func New(opts ...Option) (*Provider, error)
Creates a provider using environment variable configuration.
Returns: (*Provider, error) — error if VAULT_ADDR is not set.
Options
WithMount
func WithMount(mount string) Option
Sets the KV secrets engine mount path. Default: "secret".
WithAddress
func WithAddress(addr string) Option
Sets the Vault server address. Overrides VAULT_ADDR.
WithToken
func WithToken(token string) Option
Sets the Vault token. Overrides VAULT_TOKEN.
WithHTTPClient
func WithHTTPClient(client *http.Client) Option
Sets a custom HTTP client. Useful for testing or custom TLS configuration.
Authentication
The provider uses token-based authentication. Set the token via environment variable or option.
Environment Variable
export VAULT_ADDR="https://vault.example.com:8200"
export VAULT_TOKEN="hvs.your-token-here"
Token File
token, _ := os.ReadFile("/var/run/secrets/vault-token")
provider, _ := vault.New(vault.WithToken(string(token)))
Kubernetes
In Kubernetes, mount the token as a secret and read it at startup:
# Pod spec
volumes:
- name: vault-token
secret:
secretName: vault-token
containers:
- volumeMounts:
- name: vault-token
mountPath: /var/run/secrets/vault-token
subPath: token
readOnly: true
token, _ := os.ReadFile("/var/run/secrets/vault-token")
provider, _ := vault.New(vault.WithToken(string(token)))
For Vault Agent sidecar patterns, the agent writes a token file that your application reads.
Error Handling
The provider returns fig.ErrSecretNotFound when:
- The secret path doesn't exist
- The secret data is empty
- The requested field doesn't exist
Other errors (network, authentication) are returned as-is and cause fig.Load to fail.
Next Steps
- Secret Providers Guide — implementing custom providers
- AWS Secrets Manager — AWS integration
- GCP Secret Manager — GCP integration