Rensei docs
Providers

HashiCorp Vault

HashiCorp Vault credential provider.

The hashicorp-vault provider resolves secrets from HashiCorp Vault KV v2. It supports three authentication modes - token, AppRole, and Kubernetes - and integrates with the credential dispatch adapter's live-rotation subscription model.

The MVP ships token-auth and AppRole. Kubernetes auth (IRSA-equivalent for Vault) is the recommended production mode for containerized deployments. All three are implemented and production-exercised.

Prerequisites

  • A running HashiCorp Vault instance (OSS or Enterprise) accessible from the platform deployment.
  • KV v2 secrets engine enabled on your Vault cluster.
  • A Vault policy that allows read on the secret path {mount}/data/{orgId}/*.
  • The platform's credential encryption key must be set by the platform operator (used to encrypt the Vault config row at rest in rensei-encrypted).

Configuration

Vault is configured per-org. The config is stored as an encrypted JSON payload in a credentials row with providerType = 'vault'.

Configuration fields

FieldTypeRequiredDescription
addrURLYesVault server URL (e.g. https://vault.example.com:8200)
namespacestringNoVault Enterprise namespace
mountstringYesKV v2 mount path (e.g. secret)
authModestringYestoken, approle, or kubernetes
tokenstringIf token modeVault token (stored encrypted in rensei-encrypted)
roleIdstringIf approle modeAppRole Role ID
secretIdstringIf approle modeAppRole Secret ID
rolestringIf kubernetes modeVault Kubernetes auth role name
jwtPathstringNoOverride for the ServiceAccount JWT file path
pathTemplatestringNoOverride for the secret path template

Setup via Settings UI

Go to Settings → Security → Credential Backend.

Click Configure HashiCorp Vault.

Enter the Vault server address, mount, and auth mode.

Provide the auth-mode-specific credentials (token, AppRole roleId+secretId, or Kubernetes role name).

Click Test Connection to verify Vault is reachable and the auth credentials are valid.

Click Save. The provider registers immediately for the org.

Setup via API

curl -X POST https://rensei.ai/api/org/credential-backend \
  -H "Authorization: Bearer rsk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "providerType": "vault",
    "config": {
      "addr": "https://vault.example.com:8200",
      "mount": "secret",
      "authMode": "approle",
      "roleId": "my-role-id",
      "secretId": "my-secret-id"
    }
  }'

Secret path convention

By default, the provider looks up secrets at:

{mount}/data/{orgId}/{kind}

Where kind is the credential kind (e.g. anthropic-api-key, linear-oauth). The pathTemplate field overrides this default using {mount}, {orgId}, and {kind} placeholders.

Expected secret shape

The provider reads the data.data object from the KV v2 response and probes for the primary scalar using this field priority: valueaccessTokenapiKeytoken. If none of those keys exist but other keys do, they are exposed as multiField.

# Example Vault secret layout
vault kv put secret/org_abc123/anthropic-api-key value="sk-ant-..."
vault kv put secret/org_abc123/jira-credentials site="myorg.atlassian.net" email="bot@example.com" apiToken="..."

Authentication modes

Token mode

Simplest for development. The Vault token is stored encrypted in the Rensei credentials table. There is no upstream TTL signal - refreshAt defaults to resolvedAt + 1h.

AppRole mode

Recommended for production deployments without Kubernetes. The provider exchanges roleId + secretId for a Vault client_token at first resolve. The token is cached in-process and refreshed lazily at 80% of the lease_duration.

The AppRole secretId is itself a sensitive credential. In production, use Vault Response Wrapping to prevent the secretId from persisting in plaintext. Plain secretId storage in the config row is the MVP mode - wrapping support is a planned follow-up.

Kubernetes mode

For platform deployments on Kubernetes. The provider reads the ServiceAccount JWT from the kubelet-projected volume (default path: /var/run/secrets/kubernetes.io/serviceaccount/token) and exchanges it for a Vault token via /v1/auth/kubernetes/login. The JWT path can be overridden via jwtPath for sidecar layouts.

{
  "addr": "https://vault.example.com:8200",
  "mount": "secret",
  "authMode": "kubernetes",
  "role": "rensei-platform"
}

The Vault token returned from login is cached per (orgId, role) and renewed at 80% of lease lifetime.

Refresh policy

Auth moderefreshAt calculation
TokenresolvedAt + 1h (no upstream TTL)
AppRoleloginTime + 0.8 × lease_duration
KubernetesloginTime + 0.8 × lease_duration
KV read leaseresolvedAt + 0.8 × response.lease_duration when > 0

No background timers are spawned. Refresh happens lazily on the next resolve() call after refreshAt.

Security notes

  • Vault tokens are never logged or included in error messages. All non-2xx error paths redact the X-Vault-Token header value before throwing.
  • Kubernetes mode also redacts the ServiceAccount JWT from error messages.
  • The provider makes all HTTP calls with a 30-second timeout. Vault connection failures surface as CredentialNotFoundError to callers.
  • This provider does not auto-register. Configuring Vault in Settings activates it only for the configured org.

Health check

The Settings UI runs a health check that performs a test resolve() against the configured Vault server. You can also trigger it via the API:

curl -X POST https://rensei.ai/api/org/credential-backend/vault/health \
  -H "Authorization: Bearer rsk_live_..."
# Returns: { "ok": true, "latencyMs": 45 } or { "ok": false, "error": "..." }

On this page