@varlock/hashicorp-vault-plugin
v0.0.2
Published
Varlock plugin to load secrets from HashiCorp Vault (KV v2 secrets engine) / OpenBao
Downloads
148
Readme
@varlock/hashicorp-vault-plugin
This package is a Varlock plugin that enables loading data from HashiCorp Vault (KV v2 secrets engine) / OpenBao into your configuration.
Features
- Zero-config authentication - Automatically uses Vault token from environment or CLI
- AppRole authentication - For automated and CI/CD workflows
- Vault CLI integration - Works seamlessly with
vault loginfor local development - Auto-infer secret keys from environment variable names
- JSON key extraction from secrets using
#syntax or namedkeyparameter - Path prefixing with
pathPrefixoption for organized secret management - Default path support for sharing a common secret path across items
- Support for Vault Enterprise namespaces
- Support for multiple Vault instances
- Automatic AppRole token caching and renewal
- Lightweight implementation using REST API (no heavy Vault SDK dependencies)
Installation
If you are in a JavaScript based project and have a package.json file, you can either install the plugin explicitly
npm install @varlock/hashicorp-vault-pluginAnd then register the plugin without any version number
# @plugin(@varlock/hashicorp-vault-plugin)Otherwise just set the explicit version number when you register it
# @plugin(@varlock/[email protected])See our Plugin Guide for more details.
Setup + Auth
After registering the plugin, you must initialize it with the @initHcpVault root decorator.
Automatic auth
For most use cases, you only need to provide the Vault URL:
# @plugin(@varlock/hashicorp-vault-plugin)
# @initHcpVault(url="https://vault.example.com:8200")How this works:
- Local development: Run
vault login→ automatically uses the token from~/.vault-token - CI/CD pipelines: Wire up a token explicitly via
token=$VAULT_TOKEN - Works everywhere with zero configuration beyond the URL!
AppRole auth (For automated workflows)
For CI/CD or server environments, use AppRole authentication:
# @plugin(@varlock/hashicorp-vault-plugin)
# @initHcpVault(
# url="https://vault.example.com:8200",
# roleId=$VAULT_ROLE_ID,
# secretId=$VAULT_SECRET_ID
# )
# ---
VAULT_ROLE_ID=
# @sensitive
VAULT_SECRET_ID=You would then need to inject these env vars using your CI/CD system.
Explicit token
You can also provide a token directly:
# @initHcpVault(
# url="https://vault.example.com:8200",
# token=$VAULT_TOKEN
# )
# ---
# @type=vaultToken @sensitive
VAULT_TOKEN=Authentication Priority
The plugin tries authentication methods in this order:
- Explicit token - If
tokenis provided in@initHcpVault() - AppRole - If both
roleIdandsecretIdare provided - CLI token file - From
~/.vault-token(created byvault login) or~/.bao-token(created bybao loginfor OpenBao)
Vault Enterprise namespaces
For Vault Enterprise, specify the namespace:
# @initHcpVault(url="https://vault.example.com:8200", namespace="admin/team-a")Multiple instances
If you need to connect to multiple Vault instances, register named instances:
# @initHcpVault(id=prod, url="https://vault-prod.example.com:8200")
# @initHcpVault(id=dev, url="https://vault-dev.example.com:8200")Reading secrets
This plugin introduces the vaultSecret() function to fetch secret values from Vault's KV v2 secrets engine.
Since Vault KV v2 always stores key/value pairs, the item key (variable name) is automatically used as the JSON key to extract from the secret. You can override this with #KEY syntax or the key parameter.
# @plugin(@varlock/hashicorp-vault-plugin)
# @initHcpVault(url="https://vault.example.com:8200")
# ---
# Fetches "secret/db/config" and extracts "DB_HOST" key
DB_HOST=vaultSecret("secret/db/config")
# Override the extracted key with # syntax
DB_PASSWORD=vaultSecret("secret/db/config#password")
# Or use named "key" parameter
DB_PORT=vaultSecret("secret/db/config", key="PORT")
# Fetch entire secret as JSON blob
DB_CONFIG=vaultSecret("secret/db/config", raw=true)
# If using multiple instances
PROD_KEY=vaultSecret(prod, "secret/api/keys")
DEV_KEY=vaultSecret(dev, "secret/api/keys")Default path
Use defaultPath to set a common path for secrets when no path argument is provided:
# @initHcpVault(url="https://vault.example.com:8200", defaultPath=secret/myapp/config)
# ---
# Both fetch from "secret/myapp/config" extracting item key
DB_PASSWORD=vaultSecret()
API_KEY=vaultSecret()
# Override the inferred key using # syntax
STRIPE_KEY=vaultSecret("#stripe_api_key")
# Explicit path still extracts item key by default
OTHER_SECRET=vaultSecret("secret/other/path")
# Or override key on explicit path
OTHER_KEY=vaultSecret("secret/other/path#SPECIFIC_KEY")Path prefixing
Use pathPrefix to automatically prefix all secret paths:
# @initHcpVault(url="https://vault.example.com:8200", pathPrefix="secret/myapp")
# ---
# Fetches from "secret/myapp/db/config"
DB_HOST=vaultSecret("db/config#HOST")You can even use dynamic prefixes:
# @initHcpVault(url="https://vault.example.com:8200", pathPrefix="secret/${ENV}")
# In prod: fetches from "secret/prod/..."
# In dev: fetches from "secret/dev/..."
DB_HOST=vaultSecret("db/config#HOST")Bulk loading secrets
Use raw=true with @setValuesBulk to load all key/value pairs from a Vault path at once, instead of wiring up each secret individually:
# @initHcpVault(url="https://vault.example.com:8200")
# @setValuesBulk(vaultSecret("secret/myapp/config", raw=true))
# ---
DB_HOST=
DB_PASSWORD=
API_KEY=This fetches all keys from secret/myapp/config and maps them to matching item keys.
Reference
Root decorators
@initHcpVault()
Initialize a HashiCorp Vault plugin instance.
Parameters:
url: string(required) - Vault server URL (e.g.,https://vault.example.com:8200)token?: string- Explicit Vault authentication tokenroleId?: string- AppRole role ID for automated authenticationsecretId?: string- AppRole secret ID for automated authenticationnamespace?: string- Vault Enterprise namespacedefaultPath?: string- Default secret path when no path argument is given tovaultSecret()pathPrefix?: string- Prefix automatically prepended to all secret pathsid?: string- Instance identifier for multiple instances (defaults to_default)
Functions
vaultSecret()
Fetch a secret from HashiCorp Vault's KV v2 secrets engine.
Signatures:
vaultSecret()- UsesdefaultPath, extracts item keyvaultSecret(secretRef)- Fetch by explicit path, extracts item keyvaultSecret(secretRef, key="jsonKey")- Fetch and extract a specific keyvaultSecret(secretRef, raw=true)- Fetch all key/value pairs as JSON blob (useful with@setValuesBulk)vaultSecret(instanceId, secretRef)- Fetch from a specific Vault instance
Key extraction:
By default, the item key (variable name) is used as the JSON key to extract from the secret. You can override this with #KEY syntax in the path or the named key parameter, or use raw=true to get the full key/value blob.
Secret Ref Formats:
- Path only:
"secret/myapp/config"(extracts item key from the secret) - Path with key override:
"secret/myapp/config#DB_PASSWORD"(extracts specific key)
How paths work:
Vault KV v2 stores key/value pairs at a path. Given a path like secret/myapp/config, the plugin calls GET /v1/secret/data/myapp/config (the first path segment is the mount point, and /data/ is inserted for the KV v2 API).
Data Types
vaultToken- HashiCorp Vault authentication token (sensitive)
Vault Setup
Enable KV v2 Secrets Engine
# KV v2 is enabled by default at "secret/" in dev mode
# For production, enable it explicitly:
vault secrets enable -version=2 -path=secret kvCreate a Policy
# policy.hcl - Allow reading secrets
path "secret/data/*" {
capabilities = ["read"]
}vault policy write varlock-reader policy.hclSet Up AppRole Auth (Recommended for CI/CD)
AppRole is the recommended auth method for automated workflows:
# Enable AppRole auth method
vault auth enable approle
# Create a role
vault write auth/approle/role/varlock-role \
secret_id_ttl=24h \
token_ttl=1h \
token_max_ttl=4h \
token_policies=varlock-reader
# Get the role ID
vault read auth/approle/role/varlock-role/role-id
# Generate a secret ID
vault write -f auth/approle/role/varlock-role/secret-idSave the role_id and secret_id from the output for your CI/CD configuration.
Create a Token (For simple setups)
# Create a token with the reader policy
vault token create -policy=varlock-reader -ttl=24hStore Secrets
# Store a single key/value
vault kv put secret/myapp/config DB_PASSWORD=supersecret
# Store multiple keys
vault kv put secret/myapp/config \
DB_HOST=db.example.com \
DB_PASSWORD=supersecret \
API_KEY=abc123Troubleshooting
Secret not found
- Verify the secret exists:
vault kv get secret/myapp/config - Check the mount point is correct (first path segment, typically
secret) - Ensure you're using KV v2, not KV v1 (different API format)
Permission denied
- Check your token's policies:
vault token lookup - Ensure your policy includes
readcapability onsecret/data/*(note the/data/prefix for KV v2) - For AppRole: verify the role has the correct policies attached
Authentication failed
- Local dev: Run
vault login(orbao loginfor OpenBao) and ensureVAULT_ADDRis set correctly - CI/CD: Verify your token or AppRole credentials are properly wired up in
@initHcpVault() - Check if the token has expired:
vault token lookup - For AppRole: verify the secret ID hasn't expired and generate a new one if needed
