The bhyve yard
A FreeBSD control plane
you can actually explain.
Apiary runs a small Colony of FreeBSD hosts as one thing: bhyve VMs and jails, placed and reconciled over Raft consensus, with ZFS storage, PF networking, and a web control plane that shows its work - not a black box wrapped around libvirt.
Colony → Comb → Cell
Apiary's own vocabulary for the physical containment hierarchy it manages.
- Colony
- The whole cluster: every Comb, and everything running on them, held together by a single Raft consensus group.
- Comb
- One physical FreeBSD host. A Colony can be a single standalone Comb or several Combs joined together - both are first-class, not a degraded state.
- Cell
- One VM or jail. Placed on a Comb, reconciled continuously against its desired state, and visible cluster-wide regardless of which Comb owns it.
Built to show its work
A running list of what makes Apiary a control plane instead of a wrapper.
- Raft, not a leader-election script
- Cluster membership, placement, and configuration are Raft-committed state (hashicorp/raft), with guarded join/approve flows instead of hand-edited peer lists.
- Evidence, not vibes
- Automated assumption checks, a Why-Not engine, and a resilience coverage map explain what's actually true about the Colony right now, and what would break it.
- FreeBSD-native
- bhyve, jails, ZFS, PF, and rc.d, used the way FreeBSD already does this well - a bolt-on control plane, not a reimplementation of the OS underneath it.
Recent changes
Selected changes merged to main. Each item links to its implementation or design record.
-
14 Oct
Colony joins now enforce the full authorization flow
Approval requires a live join window, a matching unused entry in the root-owned authorization store, and two approvals from distinct API keys presented to distinct Combs - even when the Colony currently has one member. The join path also records which Comb handled each approval, checks the joining Comb's reported certificate fingerprint, and refuses repeated first authorizations.
ADR-0147 Join-flow fixes -
14 Oct
Join and authorization secrets are provisioned during setup
Installation and join setup now create the required secrets automatically, so operators do not need to prepare them by hand before using the guarded Colony join flow.
Implementation -
14 Oct
ISO upload forms reset after a successful upload
The upload form clears its file and fields after the server accepts an ISO, confirming completion and leaving the form ready for another image.
Implementation -
13 Oct
Join approvals explain the required operator actions
The approval screen now labels the two authorization steps clearly, and shows the information operators need to complete each step on the appropriate Comb.
Implementation -
28 Sep
An installer that needs no checkout
ADR-0147, Part 1apiaryctl installtakes a bare FreeBSD host to an installed Comb - configuration, certificates, and identity - from a root shell and nothing else. It changes nothing without--apply, and the part of its report worth reading is the list of what it decided not to overwrite, and why. -
28 Sep
A join window, closed by default
A new Comb can only join while the Colony's join window is open, and closed is the normal state - a request that arrives at a closed Colony is refused by name. The window is replicated Raft state rather than a flag in one Comb's config file, and it carries an epoch, so a request approved against the old window does not survive its reopening. Alongside it, every Comb now derives its peer trust anchor from a replicated trust store instead of naming its own path. TLS by default is deliberately still not done: encryption with an unverified certificate is a worse failure than no encryption, so the trust anchor has to land first.
ADR-0147, Part 4 -
28 Sep
25 mutations, 25 killed, 0 survived
The installer's test suite is now run against deliberately broken code. The one mutant that survived the first pass turned out to have found a real gap rather than a weak test - nothing asserted what the summary reports after it refuses something - so it became two new tests instead of a suppressed failure.
Commit 534512e -
27 Sep
Updating the Colony without punching a hole in quorum
A colony-wide update runs under a single-flight replicated through Raft, and managerd hands the update over cooperatively - which is what lets a controlled update restart the very daemon driving it. A restart is confirmed by its listener port, not by what
ADR-0146service(8)claims about it, and there is a test for exactly the case whereservice(8)lies. -
26 Sep
A code audit, and what it cost
15 findings across auth, join, Raft, login, and bhyve, from static analysis plus manual triage of every hit that looked real. Each one is either fixed with tests alongside it or explicitly accepted with the reason written down - including the two where the honest answer was that the exposure stays until an operator sets an allowlist.
docs/audits/2026-09-26-code-audit.md -
26 Sep
Seven states, none of which is "probably fine"
Every status badge in the UI now comes from one documented vocabulary.
ADR-0144unknownmeans the check did not complete,stalemeans the observation is aging out of its freshness window, andcontradictorymeans two evidence sources disagree with each other. Silence is a verdict rather than an all-clear, so it never renders green.
Screenshots
Current views from a live Apiary Colony: its Command Center, automated assumption checks, operational invariants, resilience coverage map, workload wizard, and image inventory.