Vault / OpenBao Provider
The Vault provider integrates with HashiCorp Vault and OpenBao for centralized secret management using the KV (Key-Value) secrets engine. Since OpenBao is an API-compatible fork of Vault, a single provider works for both.
Prerequisites
Section titled “Prerequisites”- A running Vault or OpenBao server
- Authentication credentials (see Authentication)
- KV secrets engine enabled (v1 or v2)
- Build with
--features vault
Configuration
Section titled “Configuration”URI Format
Section titled “URI Format”vault://[namespace@]host[:port][/mount][?key=value&...]openbao://[namespace@]host[:port][/mount][?key=value&...]host[:port]: Vault server address (falls back toVAULT_ADDRenv var)mount: KV engine mount path (default:secret)namespace@: Optional Vault namespace (also readsVAULT_NAMESPACEenv var)?auth=approle: Use AppRole authentication (default:token)?kv=1: Use KV v1 engine (default: v2)?tls=false: Disable TLS (for development servers)
Examples
Section titled “Examples”# Set a secret using Vault KV v2$ secretspec set DATABASE_URL --provider vault://vault.example.com:8200/secret
# Get a secret$ secretspec get DATABASE_URL --provider vault://vault.example.com:8200/secret
# Check secrets$ secretspec check --provider vault://vault.example.com:8200/secret
# Run with secrets$ secretspec run --provider vault://vault.example.com:8200/secret -- npm startSecret References
Section titled “Secret References”By default each secret is stored at secretspec/{project}/{profile}/{key} under
the mount, with a value field. A secret’s
ref field names an existing KV
entry instead: item is the KV path relative to the mount, and field selects
the field to read. field is required, since KV entries are maps. References
are read-only in this provider.
[profiles.production]DATABASE_URL = { description = "DB", ref = { item = "myapp/config", field = "db_url" }, providers = ["vault://vault.example.com:8200/secret"] }The mount is not a ref coordinate: it comes from the provider URI (secret in
the example above). To read one secret from a different mount, give that secret
a providers entry with the mount in the URI.
Basic Commands
Section titled “Basic Commands”# With default "secret" mount$ secretspec set DATABASE_URL --provider vault://vault.example.com:8200Enter value for DATABASE_URL: postgresql://localhost/mydb✓ Secret 'DATABASE_URL' saved to vault (profile: default)
# With custom mount$ secretspec set API_KEY --provider vault://vault.example.com:8200/custom-kv
# Using OpenBao$ secretspec check --provider openbao://bao.internal:8200/secretKV Version 1
Section titled “KV Version 1”# Use KV v1 engine$ secretspec set DATABASE_URL --provider "vault://vault.example.com:8200/secret?kv=1"Vault Namespaces
Section titled “Vault Namespaces”# Using namespace in URI$ secretspec check --provider vault://team-a@vault.example.com:8200/secret
# Or via environment variable$ export VAULT_NAMESPACE=team-a$ secretspec check --provider vault://vault.example.com:8200/secretSecret Naming
Section titled “Secret Naming”Secrets are stored at the KV path: secretspec/{project}/{profile}/{key}
Each secret is stored as a KV entry with a value field.
Example for KV v2: GET /v1/secret/data/secretspec/myapp/production/DATABASE_URL
Development Mode
Section titled “Development Mode”For local development with Vault in dev mode:
# Start Vault in dev mode$ vault server -dev
# Use with TLS disabled$ export VAULT_TOKEN=hvs.dev-root-token$ secretspec check --provider "vault://127.0.0.1:8200/secret?tls=false"Authentication
Section titled “Authentication”The authentication method is selected via the auth query parameter.
Token (default)
Section titled “Token (default)”Reads the token from VAULT_TOKEN environment variable or ~/.vault-token file.
export VAULT_TOKEN=hvs.your-token-heresecretspec run --provider vault://vault.example.com:8200 -- npm startAppRole
Section titled “AppRole”Authenticates using VAULT_ROLE_ID and VAULT_SECRET_ID environment variables. Useful for CI/CD pipelines and deployment platforms where a static token is not appropriate.
export VAULT_ROLE_ID=your-role-idexport VAULT_SECRET_ID=your-secret-idsecretspec run --provider "vault://vault.example.com:8200/secret?auth=approle" -- deploy