HashiCorp Vault module
Writes certificate + key + chain into a Vault KV v2 secret path. Uses Vault's built-in version history for rollback — one of the few modules where rollback is a first-class operation rather than manual cleanup. Supports AppRole, JWT, and client-TLS authentication.
01Overview
- Transport: Vault HTTP API.
- Auth: AppRole (default — role_id + secret_id), JWT (e.g. OIDC from the backend pod), TLS client cert.
- Target: KV v2 secret engine. Path template supports Go template variables (
{{ .cn }}). - Payload:
{"certificate": ..., "private_key": ..., "chain": ..., "fullchain": ...}. Field names customisable. - Rollback: supported — KV v2 keeps version history; rollback writes the previous version back as the current one.
- Namespace: Enterprise Vault namespace is supported via the
X-Vault-Namespaceheader.
02Prerequisites
- Vault cluster reachable from the backend on its API port (typically 8200 HTTPS).
- A KV v2 secret engine mounted (e.g. at
secret/). - A policy granting
create,update,read, and — for rollback —patchon the target path pattern. Sample policy for the default pathsecret/data/certs/+/...:
path "secret/data/certs/*" {
capabilities = ["create", "update", "read", "patch"]
}
path "secret/metadata/certs/*" {
capabilities = ["read", "list", "delete"]
}
03Create the module credential
- Settings → Distribution → Credentials → New → HashiCorp Vault.
-
Pick the auth method:
- AppRole: paste
role_id+secret_id. - JWT: reference an OIDC token source (service-account token for in-cluster runs).
- TLS cert: paste a PEM client certificate with the appropriate Vault cert-auth role.
- AppRole: paste
- Save.
04Create a Vault target
- Settings → Distribution → Targets → New. Module: HashiCorp Vault.
-
Fields:
- Address —
https://vault.example.com:8200. - Namespace — optional; required for Vault Enterprise namespaces.
- KV mount path —
secret(default). - Secret path template — e.g.
certs/{{ .cn }}. - Field names — customize which JSON keys hold the cert, key, chain, fullchain (defaults:
certificate,private_key,chain,fullchain). - TLS CA cert — PEM for a private-CA-signed Vault endpoint.
- TLS skip verify — for bring-up only.
- HTTP timeout — default 30 s.
- Credential.
- Address —
- Save → health check calls
sys/health.
05Execution flow
- Auth with the configured method; acquire a short-lived Vault token.
- Render the secret path template against the cert's metadata.
- POST the JSON payload to
/v1/<mount>/data/<path>. KV v2 bumps the version automatically. - On success, record the new version in
LastRollbackMetafor future rollback.
06Rollback
KV v2 keeps every version up to the engine's configured
max_versions. Clicking Rollback on the
distribution calls Vault's data/patch endpoint to
re-write the previous version as the latest — the history record
preserves the round trip. Make sure your max_versions
is high enough to cover your rollback window (10 is the default;
raise if your cadence is denser).
07Security notes
- The private key lives in Vault after distribution — if that matters to your threat model, set
include_private_keyto off (cert-only delivery). - Vault's audit log captures every write; pair it with CertAutoPilot's audit trail for a full chain of custody.
- The backend's Vault token is scoped to the policy above; it cannot read secrets outside that path pattern.
08Troubleshooting
"permission denied"
Policy is missing one of create/update/read on the target path, or the path pattern doesn't match. Test with vault token capabilities <token> secret/data/certs/example.com.
"namespace not found"
Either typo, or you hit a non-Enterprise Vault — namespaces are an Enterprise-only feature.
"kv v1 write format doesn't match"
The mount path points at a KV v1 engine. CertAutoPilot only supports KV v2. Remount or migrate.