Add a compiler VM, and put pp_role in every certificate - #63
Merged
Conversation
Two changes that only make sense together. Every node's certificate now carries a pp_role, written into csr_attributes.yaml before enrolment: openvox_server on the primary, openvox_compiler on the new node, openvox_agent on the agents. It has to happen there because pp_role is an X.509 extension — it cannot be added to a signed certificate afterwards without re-issuing it, which on the primary means replacing the certificate puppetserver is currently serving with. Provisioning it from first boot makes a rebuilt estate correct by construction rather than needing a repair step. That matters because authorization by role is the only thing separating 'this node holds a certificate from our CA' from 'this node is allowed to do X', and every agent in the estate clears the first bar. The immediate consumer is codavox, whose publisher refuses a peer without an allowed pp_role, but auth.conf works the same way. The compiler runs the same openvox-server package as the primary and differs in what it may do: its CA service is disabled and it enrols against the primary, so the estate keeps exactly one authority. That setup happens in provisioning because it has to be in place before the node holds a certificate at all. Modelled on codavox's own integration harness, which stands up the same shape and is known to work. onceover covers it: role::compiler compiles against a new factset derived from the primary's, since they are the same OS and architecture, with the identity facts and the pp_role trusted extension corrected. All five roles still pass. Not included: the compiler is absent from inventory.yaml, because Bolt validation targets the agents and reaching the compiler would also need the bolt key authorization the agent provisioners do. Add both together if that is wanted. The role module's pre-existing whitespace lint errors are untouched and unrelated; compiler.pp contributes none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Jul 26, 2026
miharp
added a commit
that referenced
this pull request
Jul 26, 2026
) Reverts #63, #64, and #65: the compiler VM, the pp_role csr_attributes, and all the codavox wiring. The tree is now identical to 0a7c5f8 apart from one Puppetfile line. This repo is a dev environment — an edit to production has to appear on the next agent run with no deploy step. codavox distributes sealed, immutable, content-addressed versions. The two models are structurally opposed, and everything added to reconcile them was paying for the mismatch: a directory of environments nested inside an environment so the publisher had something other than the working tree to seal; a working tree that cannot be sealed at all, because .onceover/ holds rspec-puppet fixture symlinks pointing at absolute macOS host paths; a compiler that could never serve production, since codavox replaces environmentpath rather than adding to it; and static catalogs turned off on the primary, a real capability lost purely to the conflict. The compiler VM goes too. Without codavox it had no code — no synced mount, and a stock empty production skeleton — so it installed openvox-server on a node that could only compile empty catalogs. codavox was the only thing that ever fed it. codavox validation moves to a control repo built for it, where r10k deploys a clean tree and static catalogs stay on. puppetlabs/yumrepo_core is kept because it is the one fix here that had nothing to do with codavox. yumrepo left Puppet core, and while site-modules/profile/.fixtures.yml already declared it for the module's own specs, the control repo never shipped it — so onceover could not compile any RedHat role, failing with "Unknown resource type: 'yumrepo'". Real nodes were unaffected because openvox-agent bundles it, which is why it went unnoticed. Verified: onceover passes all four remaining roles, and the profile suite is back to 96 examples with no failures. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.
Two changes that only make sense together, and groundwork for codavox — which distributes code to compilers, and this estate had none.
Every certificate now carries a pp_role
Written into
csr_attributes.yamlbefore enrolment:openvox_serveropenvox_compileropenvox_agentIt has to happen at provisioning because
pp_roleis an X.509 extension — it cannot be added to a signed certificate afterwards without re-issuing it. On the primary that means replacing the certificate puppetserver is actively serving with, so doing it from first boot makes a rebuilt estate correct by construction instead of needing a repair step.Why it matters: role is the only thing separating "this node holds a certificate from our CA" from "this node is allowed to do X", and every agent in the estate clears the first bar. codavox's publisher refuses a peer without an allowed
pp_role;auth.confworks the same way.The compiler
Runs the same
openvox-serverpackage as the primary and differs in what it may do: CA service disabled, enrolled against the primary, so the estate keeps exactly one authority. That is set up in provisioning because it must be in place before the node holds a certificate at all.Modelled on codavox's integration harness, which stands up the same shape and is known to work.
Verification
onceover — all five roles compile, including the new one:
role::compilerruns against a new factset derived from the primary's — same OS and architecture — with identity facts and thepp_roletrusted extension corrected.The Vagrantfile parses (
ruby -c), and the compiler's provisioner was extracted and shellcheck'd clean at warning level, since a syntactically valid Ruby heredoc can still contain broken shell.profilelint and validate clean.Deliberately not included
inventory.yaml— Bolt validation targets the agents, and reaching the compiler would also need the bolt key authorization the agent provisioners set up. Both together, if wanted.database_server.pp,example.ppandwebserver.pp. Identical on cleanproduction;compiler.ppcontributes none.Next
This is what codavox needs to be worth wiring in: a publisher on the primary distributing to a real compiler, rather than a primary serving itself. That PR follows.