vault-hc
stableHashiCorp Vault HTTP client helpers for building request paths, headers, and bodies for the Vault KV v2, Transit, AppRole, and token APIs without requiring a Vault SDK.
use plugin vault-hc::{secret_path, auth_header, wrap_secret_data, …} Functions (22)
- secret_path Build KV v2 secret read/write path
- auth_header Build X-Vault-Token header table
- wrap_secret_data Wrap a table into KV v2 write JSON
- unwrap_secret_response Extract data from KV v2 read response
- transit_encrypt_path Build transit encrypt API path
- transit_encrypt_body Build transit encrypt request JSON
- transit_decrypt_body Build transit decrypt request JSON
- seal_status_path Return the seal status API path
- health_path Return the health check API path
- list_path Build KV v2 metadata list path
- delete_path Build KV v2 data delete path
- kv_metadata_path Build KV v2 metadata path
- token_lookup_self_path Return token lookup-self path
- token_renew_self_path Return token renew-self path
- token_revoke_self_path Return token revoke-self path
- approle_login_path Build AppRole login path
- approle_login_body Build AppRole login request JSON
- namespace_header Build X-Vault-Namespace header table
- parse_seal_status Parse seal status JSON response
- parse_health_response Parse health check JSON response
- build_url Combine a Vault address and API path
- extract_client_token Extract client_token from login response
Overview
vault-hc is a stateless helper library for talking to a HashiCorp Vault server
over plain HTTP. It holds no connection and performs no network I/O itself;
instead each function is a pure builder that returns the strings, header tables,
and JSON bodies you feed into your own HTTP client. The core concept is that a
Vault request is just three pieces — a URL, an X-Vault-Token header, and
(optionally) a JSON body — and this plugin assembles each piece correctly for the
KV v2, Transit, AppRole, token, and system (seal/health) APIs.
Use it whenever you want to call Vault from Zolo without pulling in a full Vault
SDK. The typical flow is: build a path with one of the *_path helpers, turn it
into a full URL with build_url, attach a header from auth_header (or
namespace_header for Vault Enterprise), send the request with your HTTP plugin,
then parse the response with unwrap_secret_response, parse_seal_status,
parse_health_response, or extract_client_token.
Common patterns
Read a KV v2 secret: build the URL, attach the token header, then unwrap the response body into a plain table.
use plugin vault-hc::{secret_path, build_url, auth_header, unwrap_secret_response}
let url = build_url("https://vault.example.com", secret_path("secret", "myapp/db"))
let header = auth_header("s.myVaultToken")
print("GET {url} with {header["name"]}: {header["value"]}")
// after fetching `response_json` from `url` with your HTTP client:
let secret = unwrap_secret_response(response_json)
print("password: {secret["password"]}")
Write a KV v2 secret: wrap your fields in the data envelope and POST the body
to the same path.
use plugin vault-hc::{secret_path, build_url, auth_header, wrap_secret_data}
let url = build_url("https://vault.example.com", secret_path("secret", "myapp/db"))
let header = auth_header("s.myVaultToken")
let body = wrap_secret_data(#{"username": "admin", "password": "s3cr3t"})
print("POST {url}")
print(body)
Log in with AppRole and reuse the returned token for a subsequent request.
use plugin vault-hc::{approle_login_path, approle_login_body, build_url, extract_client_token, auth_header}
let login_url = build_url("https://vault.example.com", approle_login_path("approle"))
let login_body = approle_login_body("my-role-id", "my-secret-id")
print("POST {login_url}")
// after sending `login_body` and receiving `login_response_json`:
let token = extract_client_token(login_response_json)
let header = auth_header(token)
print("authenticated with header {header["name"]}")
Build KV v2 secret read/write path
Builds the full KV v2 API path for reading or writing a secret: /v1/{mount}/data/{path}.
use plugin vault-hc::{secret_path, build_url}
let url = build_url("https://vault.example.com", secret_path("secret", "myapp/db"))
print(url)
Build X-Vault-Token header table
Returns a #{"name": "X-Vault-Token", "value": token} table suitable for use as an HTTP request header.
use plugin vault-hc::{auth_header}
let header = auth_header("s.myVaultToken")
print(header["name"])
Wrap a table into KV v2 write JSON
Wraps a key-value table into a KV v2-compatible JSON string with a "data" envelope, ready to POST to Vault.
use plugin vault-hc::{wrap_secret_data, secret_path, build_url}
let body = wrap_secret_data(#{"username": "admin", "password": "s3cr3t"})
print(body)
Nested tables are preserved, so you can store structured configuration in a single secret:
use plugin vault-hc::{wrap_secret_data}
let body = wrap_secret_data(#{
"host": "db.internal",
"port": 5432,
"tls": #{"enabled": true, "ca": "letsencrypt"}
})
print(body)
Extract data from KV v2 read response
Parses a KV v2 read response JSON string and extracts the data.data field, returning your secret fields directly as a table.
use plugin vault-hc::{unwrap_secret_response}
let secret = unwrap_secret_response(response_json)
print(secret["password"])
If the JSON is not a KV v2 envelope (no data.data wrapper), the whole parsed
object is returned as-is, so it also works for flat responses:
use plugin vault-hc::{unwrap_secret_response}
let flat = unwrap_secret_response("{\"api_key\": \"abc123\"}")
print(flat["api_key"])
Build transit encrypt API path
Returns the Vault Transit encrypt path /v1/transit/encrypt/{key_name}.
use plugin vault-hc::{transit_encrypt_path, build_url}
let url = build_url("https://vault.example.com", transit_encrypt_path("mykey"))
Build transit encrypt request JSON
Builds the JSON body for a Transit encrypt request. The plaintext is base64-encoded automatically as required by the Vault Transit API.
use plugin vault-hc::{transit_encrypt_body}
let body = transit_encrypt_body("my secret value")
print(body)
Pair it with transit_encrypt_path and build_url to assemble the full
encrypt request:
use plugin vault-hc::{transit_encrypt_path, transit_encrypt_body, build_url}
let url = build_url("https://vault.example.com", transit_encrypt_path("orders-key"))
let body = transit_encrypt_body("card-number-4242")
print("POST {url}")
print(body)
Build transit decrypt request JSON
Builds the JSON body for a Transit decrypt request given a ciphertext string (e.g. "vault:v1:...").
use plugin vault-hc::{transit_decrypt_body}
let body = transit_decrypt_body("vault:v1:abc123...")
print(body)
Return the seal status API path
Returns the Vault seal status path /v1/sys/seal-status. Use this to check whether Vault is sealed before making secret requests.
use plugin vault-hc::{seal_status_path, build_url}
let url = build_url("https://vault.example.com", seal_status_path())
Return the health check API path
Returns the Vault health path /v1/sys/health for liveness/readiness checks.
use plugin vault-hc::{health_path, build_url}
let url = build_url("https://vault.example.com", health_path())
Build KV v2 metadata list path
Builds the KV v2 metadata LIST path /v1/{mount}/metadata/{path} for enumerating secrets.
use plugin vault-hc::{list_path}
let path = list_path("secret", "myapp/")
print(path)
Build KV v2 data delete path
Builds the KV v2 data delete path /v1/{mount}/data/{path}.
use plugin vault-hc::{delete_path}
print(delete_path("secret", "myapp/old-key"))
Build KV v2 metadata path
Builds the KV v2 metadata path /v1/{mount}/metadata/{path} for reading or deleting all versions of a secret.
use plugin vault-hc::{kv_metadata_path}
print(kv_metadata_path("secret", "myapp/db"))
Return token lookup-self path
Returns /v1/auth/token/lookup-self for inspecting the current token's properties.
use plugin vault-hc::{token_lookup_self_path}
print(token_lookup_self_path())
Return token renew-self path
Returns /v1/auth/token/renew-self for renewing the current token's lease.
use plugin vault-hc::{token_renew_self_path}
print(token_renew_self_path())
Return token revoke-self path
Returns /v1/auth/token/revoke-self for revoking the current token.
use plugin vault-hc::{token_revoke_self_path}
print(token_revoke_self_path())
Build AppRole login path
Returns the AppRole login path /v1/auth/{mount}/login. Defaults to "approle" if no mount is provided.
use plugin vault-hc::{approle_login_path}
print(approle_login_path("approle"))
print(approle_login_path("my-approle"))
Build AppRole login request JSON
Builds the JSON body for an AppRole authentication request.
use plugin vault-hc::{approle_login_body, approle_login_path, extract_client_token}
let body = approle_login_body("my-role-id", "my-secret-id")
print(body)
Build X-Vault-Namespace header table
Returns a #{"name": "X-Vault-Namespace", "value": namespace} header table for Vault Enterprise namespace routing.
use plugin vault-hc::{namespace_header}
let hdr = namespace_header("team-a/")
print(hdr["value"])
Parse seal status JSON response
Parses a Vault seal status JSON response into a table. The table includes fields like sealed, initialized, cluster_name, and version.
use plugin vault-hc::{parse_seal_status}
let status = parse_seal_status(response_json)
print(status["sealed"])
Combine it with seal_status_path and build_url to check whether Vault is
ready before issuing secret requests:
use plugin vault-hc::{seal_status_path, build_url, parse_seal_status}
let url = build_url("https://vault.example.com", seal_status_path())
print("GET {url}")
// after fetching `response_json` from `url`:
let status = parse_seal_status(response_json)
if status["sealed"] {
print("vault is sealed — unseal before continuing")
}
Parse health check JSON response
Parses a Vault health check JSON response into a table.
use plugin vault-hc::{parse_health_response}
let health = parse_health_response(response_json)
print(health["version"])
Combine a Vault address and API path
Concatenates a Vault server address and an API path, trimming any trailing slash from addr.
use plugin vault-hc::{build_url, secret_path}
let url = build_url("https://vault.example.com/", secret_path("secret", "config"))
print(url)
It works with any path helper, so the same call builds system, token, and metadata endpoints:
use plugin vault-hc::{build_url, health_path, token_lookup_self_path}
let addr = "https://vault.example.com"
print(build_url(addr, health_path()))
print(build_url(addr, token_lookup_self_path()))
Extract client_token from login response
Parses a Vault login response JSON string and extracts auth.client_token. Returns the token string, or nil if not present.
use plugin vault-hc::{approle_login_body, extract_client_token}
let token = extract_client_token(login_response_json)
print("Token: {token}")