Authentication
Vault token vs. AppRole, credential mapping, namespaces, and token caching
system/health and system/sealStatus
requires authMethod and credentialID. Those two System operations are
unauthenticated by design — see System Operations.
Shared Auth Config Keys
| Field | Required | Description |
|---|---|---|
authMethod | ✓ Yes* | "token" or "appRole". *Not required for system/health/system/sealStatus. |
credentialID | ✓ Yes* | BizFirst credential record ID, resolved via IHashiCorpCredentialResolver. *Same exemption as above. |
appRolePath | No | Vault auth-method mount path. Default "approle". Only meaningful when authMethod is "appRole"; lets a tenant use a custom mount. |
namespace | No | Vault Enterprise namespace, sent as the X-Vault-Namespace header. Slash-separated (e.g. parent/child) — no leading/trailing slash or empty segment. |
authMethod: "token"
A pre-issued Vault client token. Resolved via the platform's existing
ICredentialResolver.GetBearerTokenAsync(credentialID) — the same mechanism other
bearer-token-authenticated nodes use. The resolved token is sent as Vault's X-Vault-Token
header on every call.
authMethod: "appRole"
A role_id/secret_id pair, stored as a BizFirst
PasswordRecord by this node's own convention:
| PasswordRecord field | Holds |
|---|---|
Username | AppRole role_id |
Password | AppRole secret_id |
The pair is exchanged for a Vault client token via POST /v1/auth/{appRolePath}/login.
This mapping is not a native PasswordRecord field — it's this node's own convention, so
it's worth confirming your stored credential matches it exactly.
Client Token Caching
The exchanged client token is cached in-process, keyed by credentialID
(IHashiCorpAppRoleTokenCache, registered as a singleton so it outlives the scoped
credential resolver). A per-credentialID semaphore makes concurrent executions sharing a
credential single-flight through one login, rather than each consuming a secret_id.
- The cache honors Vault's returned
lease_duration, renewing 30 seconds before actual expiry so an in-flight call never expires mid-request. - If Vault returns a
lease_durationof 0 or below the 30-second safety buffer, the token is used but not cached — the next call re-authenticates rather than risk caching something with no reliable expiry.
secret_id: if a tenant's
AppRole is configured with secret_id_num_uses = 1 (HashiCorp's own recommended
hardening pattern), the cache above only masks the problem, it doesn't eliminate it: the first login
consumes the single-use secret_id, subsequent calls are served from cache for as long as
the cached token's TTL lasts, but once that token expires there is no secret_id left to
log in again — every call from then on fails with HASHICORP_AUTH_FAILED. Until this is
resolved (see Roadmap), use an AppRole with
secret_id_num_uses = 0 (unlimited) for any credential this node authenticates with.
Vault Enterprise Namespaces
Set namespace (e.g. parent/child) to scope every call to a specific Vault
Enterprise namespace. The value is validated against
^[A-Za-z0-9_-]+(/[A-Za-z0-9_-]+)*$ at config-validation time — a typo'd namespace fails
fast with HASHICORP_INVALID_CONFIGURATION instead of surfacing as an opaque Vault 400/404
later.