Support wire-compatible auto-renewal (no CSR) on /certificate_renewal#113
Open
bootc wants to merge 1 commit into
Open
Support wire-compatible auto-renewal (no CSR) on /certificate_renewal#113bootc wants to merge 1 commit into
bootc wants to merge 1 commit into
Conversation
Real Puppet/OpenVox agents renew their client certificate by default (hostcert_renewal_interval, default 30d) by POSTing an empty body to /certificate_renewal and relying solely on the mTLS-presented client certificate to prove identity and key possession; they expect the SAME key reissued with a fresh serial and validity. Our CSR-only handler rejected every such request with 400, so this endpoint silently never worked against a stock agent. Add CA.AutoRenew, matching OpenVox Server's own Clojure CA (renew-certificate! in certificate_authority.clj): it builds the new certificate straight from the already-issued certificate presented over mTLS (no CSR lookup at all, so it also covers certs whose CSR was deleted after signing or that arrived via migration import), carrying forward SANs and Puppet OID extensions, and reissues under the same key. Extract the shared "build template, sign, persist" tail out of signWithDuration into issueLeafLocked so both paths share it. /certificate_renewal now branches on an empty body to this path, keeping the existing CSR re-key path for non-empty bodies. Add a real-agent regression test (Group 3b in test/puppet/puppet-stack.sh) that drives `puppet ssl renew_cert` against a live openvox-ca instance, since this is exactly the code path real agents exercise and unit tests alone would not catch a wire-format mismatch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Real Puppet/OpenVox agents renew their client certificate by default (
hostcert_renewal_interval, default 30d) by POSTing an empty body to/certificate_renewaland relying solely on the mTLS-presented client certificate to prove identity and key possession — they never send a CSR, and expect the SAME key reissued with a fresh serial and validity. Our existing CSR-only handler rejected every such request with a 400, so a stock agent's automatic renewal silently never worked against openvox-ca (the agent logs a warning and keeps using its current cert).This adds
CA.AutoRenew, matching OpenVox Server's own Clojure CA (renew-certificate!incertificate_authority.clj): it builds the new certificate directly from the already-issued certificate presented over mTLS — no CSR lookup at all, so it also covers certificates whose CSR was deleted after signing (the normal case) or that arrived via migration import with no CSR ever recorded. It carries forward the original certificate's SANs and Puppet OID extensions, and reissues under the same key.POST /certificate_renewalnow branches on an empty body to this path; a non-empty body keeps using the existing CSR re-key path unchanged.The internals of
signWithDurationwere split so the "build template, sign, persist" tail (issueLeafLocked) is shared between the CSR path andAutoRenew.Real-agent regression test: added Group 3b to
test/puppet/puppet-stack.sh, which drives the actualpuppet ssl renew_certCLI action (the same code path a stock agent's automatic renewal takes) against a live openvox-ca instance in the compose-puppet stack, and asserts: exit 0, a new serial, the same public key, and that the renewed cert still works for a normal agent run. This is deliberately end-to-end with the realopenvox-agentpackage rather than a Go-mocked TLS cert, since the bug this PR fixes is specifically a wire-format mismatch that unit tests alone would not catch.Scope note: OpenVox Server's Clojure CA does not revoke the certificate being replaced during this kind of renewal — both the old and new certs (same key) stay valid until the old one naturally expires. This PR preserves that behaviour to match. A follow-up PR (#114, based on this branch) adds revocation of the superseded certificate as a configurable, secure-by-default option.
🤖 Generated with Claude Code