hashicorp / hashicorp/vault

pkiCert: support the PKI engine's `pkcs12_bundle` and `jks_bundle` formats

Open
#32,112 0 comments 1 reaction 0 assignees View on GitHub
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.**
Vault Agent's `pkiCert` template function uses its destination file as the certificate cache, which is what makes it safe across agent restarts and token re-authentications: it only calls Vault when the certificate on disk is missing or due for rotation. It only understands PEM, though. The PKI engine can return `format=pkcs12_bundle` or `format=jks_bundle`, where the `certificate` field holds a base64 archive carrying the key, the certificate and the chain together, and the services that ask for a keystore (a JVM, .NET) are the ones that need it. Those consumers currently have to fall back to `secret`, which fetches a fresh certificate on every agent restart and every token re-auth and times rotation from the lease rather than from the certificate. With `format=pkcs12_bundle` in the arguments, `pkiCert` concatenates the response's string fields, finds no PEM block in the base64 archive, treats the certificate as missing and fetches again on every cycle; writing the archive to the destination does not help, since the read-back finds no PEM either, and the archive itself is not reachable from the returned struct.

**Describe the solution you'd like**
When `format=` names one of the two bundle formats, `pkiCert` should take the archive from the response's `certificate` field, base64-decode it and expose the raw bytes as a field (say `.Bundle`) so a template can write it verbatim as the destination, the way templates already write binary through `base64Decode`. On read-back it should parse the destination instead of scanning for PEM: PKCS#12 with `software.sslmate.com/src/go-pkcs12` (`DecodeChain`, password from the `pkcs12_password` argument, default `changeit`) and JKS with `github.com/pavlo-v-chernykh/keystore-go/v4` (`jks_password`, `jks_private_key_alias`), which are the libraries Vault encodes with, so a decode round-trips. The leaf then feeds the existing rotation logic exactly as the PEM path does, and `.Cert`, `.Key`, `.CA` and `.CAChain` can be populated from the decoded archive as well, so one template can emit the keystore and PEM siblings together. The format and the passwords are already explicit in the template arguments, so no content sniffing is needed and no new secret is exposed, and PEM callers are untouched. The change itself lives in consul-template's `dependency/vault_pki.go`; I am filing it here because `pkiCert` and the bundle formats are both Vault features.

**Describe alternatives you've considered**
Keeping `secret` for keystores works but re-issues on every restart and re-auth, and behind an ACME-backed mount that is a new order each time. Rendering PEM with `pkiCert` and exporting the keystore with `openssl pkcs12 -export` from an `exec` needs OpenSSL on every host and puts the private key on disk as PEM, which is exactly what asking Vault for a keystore avoids.

**Explain any additional use-cases**
Any Vault Agent deployment feeding a Java or .NET service: the keystore is the only artefact those services read, and today it is the one certificate shape that cannot be cached.

**Additional context**
In our fleet, a Java service and a .NET service are both minted with `format=pkcs12_bundle` through `secret` and re-issued at every ~46 h AppRole token re-auth, while every other certificate has moved to `pkiCert` and stays put across restarts. Happy to contribute the consul-template PR if the approach is acceptable.

Contributor guide

Open the contributing guide

Research direction

Start in consul-template's dependency/vault_pki.go and trace the existing pkiCert PEM caching and rotation path. Review the specified PKCS#12 and JKS decoding libraries and relevant package tests. Done means bundle formats cache and round-trip from the destination, expose the raw bundle and decoded certificate fields, and leave PEM behavior unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.