Skip to main content

HashiCorp Vault module

Writes certificate + key + chain into a Vault KV secret path (KV v1 or v2, selected per target). On KV v2 it 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 Token and AppRole authentication.

Overview

  • Transport: Vault HTTP API.
  • Auth: Token (paste a Vault token) or AppRole (role_id + secret_id).
  • Target: KV secret engine — KV v1 or KV v2, selected per target via the engine_type field (kv1 | kv2, default kv2). The secret path is a literal string (no templating) — leave it empty for a per-certificate auto path, or override it per distribution.
  • Payload: {"certificate": ..., "private_key": ..., "chain": ...}. The private key is always written; scope which secrets the token may read via the Vault policy. 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-Namespace header.

Prerequisites

  • Vault cluster reachable from the backend on its API port (typically 8200 HTTPS).
  • A KV secret engine mounted (e.g. at secret/) — KV v1 or KV v2. Version-history rollback requires KV v2.
  • A policy granting create, update, and read on the target path pattern. Auto-generated paths live under the certautopilot/ directory, so a policy covering secret/data/certautopilot/* and secret/metadata/certautopilot/* works out of the box:
path "secret/data/certautopilot/*" {
capabilities = ["create", "update", "read"]
}
path "secret/metadata/certautopilot/*" {
capabilities = ["read", "list", "delete"]
}

Create the module credential

  1. Settings → Distribution → CredentialsNewHashiCorp Vault.
  2. Pick the auth method:
    • Token: paste a Vault token.
    • AppRole: paste role_id + secret_id.
  3. Save.

Create a Vault target

  1. Settings → Distribution → TargetsNew. Module: HashiCorp Vault.
  2. Fields:
    • Addresshttps://vault.example.com:8200.
    • Namespace — optional; required for Vault Enterprise namespaces.
    • KV mount pathsecret (default).
    • Engine typekv2 (default) or kv1. KV v2 is required for version-history rollback.
    • Secret path — optional. Empty = auto-generated per certificate as certautopilot/cap-<token>-<domain> (token: 8-char hash derived from the certificate, stable across renewals), so one target can serve many certificates. Can also be overridden per distribution from the certificate's Distributions → Overrides drawer.
    • 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.
  3. Save → health check calls sys/health.

Execution flow

  1. Auth with the configured method; acquire a short-lived Vault token.
  2. Resolve the secret path (explicit target path, per-distribution override, or the per-certificate auto path certautopilot/cap-<token>-<domain>).
  3. POST the JSON payload to /v1/<mount>/data/<path>. KV v2 bumps the version automatically.
  4. On success, record the new version in LastRollbackMeta for future rollback.

Rollback

KV v2 keeps every version up to the engine's configured max_versions. Clicking Rollback on the distribution reads the previous version and writes it back 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).

Security notes

  • The private key is always written to Vault as part of the payload — if that matters to your threat model, scope the backend's Vault policy tightly (and audit reads) so only the intended consumers can retrieve the secret.
  • 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.

Troubleshooting

"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/certautopilot/cap-1a2b3c4d-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 points at a KV v1 engine but the target's Engine type is set to kv2 (or vice versa). Set engine_type to match the mount — both KV v1 and KV v2 are supported. No migration is needed; only the version-history rollback feature requires KV v2.

See also