Files
certctl/docs/reference/connectors/vault.md
T
shankar0123 430180360d docs: Phase 4 follow-on batch 1 — 5 issuer per-pages
Extract the first 5 issuer per-connector deep-dive pages:

- vault.md (128 lines) — Vault PKI synchronous issuance, token TTL +
  auto-renewal loop, MaxTTL enforcement, rotation playbook
- digicert.md (106 lines) — CertCentral DV/OV/EV with bounded async
  polling for vetting workflows
- aws-acm-pca.md (165 lines) — managed private CA on AWS with full
  IAM policy, IRSA wiring, troubleshooting matrix
- ejbca.md (116 lines) — open-source / Keyfactor EJBCA with mTLS or
  OAuth2 auth, mTLS keypair caching, approval-pending guidance
- adcs.md (111 lines) — Active Directory Certificate Services as
  enterprise root via Local CA sub-CA mode, sub-CA rotation playbook

Index updated with forward-list entries and the index-purpose blurb
revised so the index now positions itself as 'navigate from here;
deeper material lives in siblings' rather than 'docs to be extracted
later'.

Each per-page follows the WHAT/HOW/WHY pattern: what the connector is,
how authentication and issuance work, and when to choose this vs an
alternative. Cross-links to the connector index, async-ca-polling
primitive, and adjacent operator runbooks.

This is part 1 of 4 for the Phase 4 follow-on (per-connector page
extraction) tracked in cowork/docs-overhaul-phase-2-restructure-2026-05-04/log.md.

Net add: 5 files, 626 lines. No content removed from index.md (the
index keeps its inline reference; per-pages add operator depth on
top, matching the pattern set by apache/f5/iis/k8s/nginx in Phase 4
structural).
2026-05-05 03:53:52 +00:00

5.3 KiB

Vault PKI Issuer Connector — Operator Deep-Dive

Last reviewed: 2026-05-05

Operator-grade documentation for the HashiCorp Vault PKI issuer connector. For the connector-development context (interface contract, registry, ports/adapters), see the connector index.

Overview

The Vault PKI connector integrates with HashiCorp Vault's PKI secrets engine using its native /sign API with token-based authentication. The flow is purely synchronous — Vault returns the signed certificate in the same HTTP response that submits the CSR — so there is no challenge-solving or async polling on the certctl side.

Implementation lives at internal/connector/issuer/vault/. The factory key is Vault; the registry binds it under whatever issuer ID the operator picks (e.g. iss-vault).

When to use this connector

Use the Vault PKI connector when:

  • Your organization already runs Vault as the system of record for internal certificates.
  • You want a synchronous, low-latency issuance path with no challenge flow (no DNS records, no HTTP-01).
  • You want certctl to manage the lifecycle (renewal scheduling, deployment, alerts) while Vault keeps the signing material.

Look elsewhere when:

  • Public-trust certificates are required — Vault PKI is internal-only. Use ACME (Let's Encrypt, ZeroSSL, Sectigo) or DigiCert / Sectigo SCM for public-trust workloads.
  • The Vault PKI engine is not already deployed and you don't want to run Vault. The Local CA issuer is a simpler self-contained path for small internal CAs.

Configuration

Variable Default Description
CERTCTL_VAULT_ADDR Vault server address (e.g. https://vault.internal:8200)
CERTCTL_VAULT_TOKEN Vault auth token with permissions on the PKI mount
CERTCTL_VAULT_MOUNT pki PKI secrets engine mount path
CERTCTL_VAULT_ROLE PKI role name for certificate signing
CERTCTL_VAULT_TTL 8760h Certificate validity period (TTL)

Vault issues certificates synchronously via the /v1/{mount}/sign/{role} API with X-Vault-Token header authentication. The issued certificate is parsed to extract serial number, validity dates, and chain information.

Token TTL and automatic renewal

This was Top-10 fix #5 from the 2026-05-03 issuer-coverage audit.

certctl-server periodically calls POST /v1/auth/token/renew-self at half the token's TTL to keep the integration alive without manual rotation. The cadence is read from a one-shot lookup-self at startup and re-derived on every successful renewal — so a short bootstrap token that gets renewed up to a longer Max TTL shifts to the longer cadence automatically.

The renewal loop emits the certctl_vault_token_renewals_total{result="success"|"failure"|"not_renewable"} Prometheus counter so operators see expiry trouble in Grafana before issuance breaks.

When Vault returns renewable: false (configured Max TTL reached), the loop logs a WARN, increments {result="not_renewable"}, and exits. The operator must rotate the Vault token and either restart certctl-server or use the GUI / MCP issuer-update path to swap the token in place — the registry's Rebuild path re-Starts the lifecycle on the new connector.

Per-tick failures (e.g. transient 5xx, brief network blips) bump {result="failure"} and the loop keeps ticking. Only the explicit renewable: false case stops it.

MaxTTL enforcement (M11c)

When a certificate profile defines a maximum TTL, the Vault connector overrides the TTL string in the signing request to ensure the issued certificate does not exceed the profile limit. This is applied before Vault's own role-level max TTL — so the effective limit is the minimum of (profile.MaxTTL, role.MaxLeaseTTL).

Revocation and CRL/OCSP

CRL and OCSP are managed by Vault itself. Clients should validate certificate status against Vault's own CRL/OCSP endpoints (GET /v1/{mount}/crl and Vault's OCSP responder). certctl does not generate local CRL/OCSP for Vault-issued certificates. Revocation is recorded locally (audit row + cert state) but Vault is the authoritative source for relying parties.

Operator playbook

Token rotation without downtime

Two paths:

  1. Restart-driven. Update CERTCTL_VAULT_TOKEN env var on the server, restart certctl-server. The renewal loop picks up the new token's lookup-self response and resumes ticking.
  2. Hot-swap via API/GUI. PUT /api/v1/issuers/{id} with the updated config; the registry's Rebuild path replaces the connector without restart. Use this when Vault's Max TTL has been reached and the existing token can no longer be renewed.

Diagnosing renewal failures

Watch certctl_vault_token_renewals_total{result="not_renewable"} and {result="failure"}. Sustained failures with no not_renewable generally indicate Vault unreachability or token-policy drift; a spike in not_renewable is the canonical signal that a Max TTL boundary was hit and operator action is required.