hashicorp / hashicorp/vault

api: support client-side CRL validation of the Vault server's TLS certificate

Open
#32,092 1 comment 1 reaction 0 assignees View on GitHub
enhancement tls
Dominant language
Go
Stars
36.3k
Forks
4.8k
PR merge metrics
PR metrics pending

Description

**Is your feature request related to a problem? Please describe.**
The Vault Go API client (`github.com/hashicorp/vault/api`) currently does not check if the Vault server's TLS certificate was revoked. `TLSConfig` supports `CACert`, `CACertBytes`, `CAPath`, `ClientCert/ClientKey`, `TLSServerName`, and `Insecure`, but there is no `CRLPath`, `CRLBytes`, or hook to plug in custom revocation-checking logic (source: [api/client.go](https://github.com/hashicorp/vault/blob/main/api/client.go), `TLSConfig` struct and `configureTLS()`).

If a server certificate is revoked (compromised key, decommissioned node, etc.), Go API clients using `vault/api` will continue to trust it until it expires, since the standard `crypto/tls`/`crypto/x509` chain verification does not check CRLs unless the application wires that up itself.

**Describe the solution you'd like**
Add first-class support for client-side CRL checking of the Vault server certificate to `TLSConfig`/`Config`, for example:
- `CRLPath` / `CRLBytes` fields on `TLSConfig`, analogous to the existing `CACert`/`CACertBytes` pattern.
Internally, wire these into a `tls.Config.VerifyPeerCertificate` or `VerifyConnection` callback that checks the presented server certificate chain against the supplied CRL(s), following the pattern used by `google.golang.org/grpc/security/advancedtls's `RevocationOptions`/`CRLProvider`.
- Document the interaction with TLS session resumption (see Implementation Constraints below), and consider disabling session tickets/resumption for connections where CRL checking is enabled, so the check isn't silently bypassed on resumed connections.

**Describe alternatives you've considered**
- Custom `http.Client`/`tls.Config` injection: A caller can build their own `*http.Client` with a custom `VerifyPeerCertificate` and set it via `Config.HttpClient` before calling `api.NewClient`. This works but is undocumented as a supported extension point for this use case, and every consumer of the library has to reimplement CRL fetching/parsing/caching themselves (there's no shared, tested implementation).
- OCSP instead of CRL: Vault's PKI engine already supports OCSP responders, which some clients may prefer for near-real-time status. This issue is scoped to CRL specifically since that's the most portable/offline-friendly mechanism and matches the parity already present for CA/cert configuration.

**Explain any additional use-cases**
- Air-gapped or otherwise disconnected environments running an internal Vault PKI, where OCSP round-trips aren't available/desirable but a periodically-refreshed CRL file is.
- Environments that rotate the Vault listener certificate and want a defense-in-depth mechanism so any Go client immediately stops trusting the old (revoked) server certificate, rather than waiting for expiry.

**Additional context**
N/A

Contributor guide

Open the contributing guide

Research direction

Start in api/client.go by reading TLSConfig and configureTLS(), then compare the revocation flow in google.golang.org/grpc/security/advancedtls. Define how CRLPath and CRLBytes should be parsed and applied to the presented certificate chain, including TLS session resumption. Done means configured clients reject revoked Vault server certificates while preserving existing TLS behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.