Wheelhouse docs

What is finished, and what is not#

Wheelhouse is a working router platform with real gaps. This page is the list of both, before you move a network onto it. The same list is on the status page of the product site.

Built, and exercised#

What that means concretely
The agentA Go binary fronting the VyOS API: staging, native commit-confirm, revision rollback, an attributed audit log whose entries carry a sequence number and the hash of the entry before them, parsed operational state (counters, conntrack, routes, leases, certificates, logs) and a live telemetry WebSocket. Accounts with Argon2id and TOTP, sessions with CSRF, four roles, scoped API tokens, OIDC as a relying party, Prometheus metrics, TLS, an OpenAPI 3.1 document generated from its own route table, and the web UI served from the directory --ui-dir names
The web UIA React single-page application: a page per left-nav entry across seven groups, with the pages the account pinned above them, every editor rendering the set and delete lines it will run in Advanced mode, one Commit Bar, live state beside configured intent with drift flagged, a search over pages and the objects they edit, dark by default and light one click away
The app store40 catalogue entries: 37 containers declared in the router's configuration tree, plus three built-in feature modules. An install is staged as configuration, so it appears in the diff and rolls back with a revision
Migration and unattended installAn OPNsense config.xml becomes VyOS commands plus a report of what could not come across; --check-against compares a running router with the configuration it should have. The installer finds a seed and installs with nobody at the keyboard — which no published 0.6.x image does, for the reason under the next table
Multi-WANUplinks through every VyOS mechanism, health-checked failover, load balancing, policy routing and per-uplink NAT — proven on a dual-WAN VM built from the ISO
Inline IPSSuricata in the packet path through NFQUEUE, entirely in the configuration tree, so it diffs, commits and rolls back, with two fail-open layers
A support bundleOne command produces the whole diagnosis: wheelhouse-agent support-bundle, wheelhouse-support at the console, or System → Support in the web UI. Up to nineteen entries in one .tar.gz — two of them never appear together — with every collected artefact passed through the agent's own redaction, capped at 4 MiB per artefact and 16 MiB in total, with a manifest.json naming each source that failed, was empty or was left out on purpose
A way back inEnrolling a second factor issues ten single-use recovery codes, shown once, and one signs you in at the login prompt. An admin clears another account's factor from Admin → Users. The install medium carries Rescue an installed Wheelhouse system in both bootloaders, and that boot lands on wheelhouse-rescue: reset a web UI password, clear a second factor, re-run first boot, restore a configuration, or ask why the agent will not start — Locked out
The image pipelineEvery tag builds the .deb and the ISO, inspects the image before publishing it, and publishes both with one checksum file, a corresponding-source record and an update channel index

What has actually been run#

Status
Booting the live image in a VMYes, repeatedly
Installing to a disk in a VM and rebooting into itYes, by keyboard for 0.4.5. Unattended from a seed for 0.5.0, carrying a real router's 214-command configuration — it came back up with the LAN address, 20 DHCP reservations, the port forwards, Kea, CAKE and the agent running — and again from the current tree, after the regression below
An unattended install on 0.6.0, 0.6.1 or 0.6.2It never worked. See the warning below
Refusing to reinstall over itself with the seed medium still plugged inYes, on the same VM
Booting the live image on physical hardwareYes
A complete install to disk on physical hardware, then a reboot into itYes, several times, on one machine
A second machineNot recorded. One machine is not a compatibility list
An add system image upgrade of a Wheelhouse boxIn a VM only, once, on 2026-09-03. None on hardware
Any measurement of CPU, memory or throughputNone. The performance budget in the systemd unit is a target, not a measurement

If you are evaluating this, install it in a VM first. That is still the path with the most evidence behind it, and it exercises the same installer, the same units and the same first-boot sequence as the metal.

Not finished#

  • The hardware evidence is one machine. The image installs to a disk and reboots into it on one physical machine, and that is the whole of the metal record: there is no hardware compatibility list and no second board. There is also no VM image — no qcow2, no OVA — and images are amd64 only, booting UEFI or legacy BIOS. The arm64 .deb exists for running the agent off-router against an arm64 router; there is no arm64 image.
  • The end-user terms are a placeholder, marked as one in their own first paragraph. Nothing should be sold until real terms replace them — The Wheelhouse licence.
  • IPv6 is not yet everywhere IPv4 is. Network → IPv6 shows v6 addresses, neighbours, routes and ip6 counters, and edits addressing, router advertisements and prefix delegation; static routes are edited for both families. The neighbour tables are v4, and the uplink model has no v6 concept; the Firewall page is v4-first.
  • Nothing signs the audit log, and no router ships with a witness. The chain and the syslog export are described below; what neither buys is a signature, and the export sends nothing until you name a collector.
  • App images are pinned, and pinning is a manual step. All 37 container entries carry name:tag@sha256:…, so what a diff approves is the bytes that install, and CI refuses a catalogue that goes back to a floating tag. Moving to a newer upstream image is a deliberate re-pin that produces a diff someone reads, so a pinned image ages until somebody does that.
  • Releases are not signed. The pipeline signs checksums the moment a key exists; no key does. A checksum proves the download survived the network, not who built it.
  • The interface is tested in jsdom, not in a browser. CI runs the agent's test suite with the race detector, and the web UI's suite beside the type-check and build. That suite renders nearly every page against answers mostly captured from real routers, and holds each to what it shows and what it stages; it also covers the sentences pending changes are described in, the search, the sidebar and the QR encoder's vectors. The configuration tree, reconcile, Support, About and the licence page have no test, and neither do some tabs of the pages that do. jsdom sees no layout, no focus order and no telemetry socket, so an overflowing table, a panel off the edge of a phone or a live view that stops updating is found only by looking, and that is done by hand, in a browser, before each release.
  • A packet capture outlives the page that started it, by about twenty seconds. Diagnostics → Capture runs a bounded tcpdump on the router and ends in a downloadable pcap. With Stop it when nobody is watching — on by default — the agent ends it 20-25 seconds after the last time any signed-in page asked how it was doing, with reason unwatched and an audited stop against whoever started it; unticked, only its limits do, at most 300 seconds. What the page no longer does is lie about the file afterwards: it keeps watching, slowly, for as long as a pcap exists, and the download goes when the 15-minute retention deletes it. An agent that starts up sweeps the capture directory, so the pcap an agent killed mid-retention left behind no longer waits on the router for somebody to start another capture.
  • The audit log on disk holds whatever was committed, secrets included. An entry stores the commands exactly as they were sent, so a commit that carried a WireGuard private key someone typed writes that key into the file, into the syslog export and into the hash chain. GET /api/audit redacts it below operator, but the file is secret material and a collector receiving it is holding secrets. A key the agent generated — a WireGuard tunnel's, an OpenVPN client's, a TLS key — is recorded as [redacted].
  • IPv6, like every op-mode read, is served from a 3-second cache that answers first and refreshes behind. The first read after a commit can therefore show the v6 tables as they were before it — the ip6 ruleset tile can read 0 for a router that already has one, for one poll.
  • The release gate has never decided a release. iso.yml installs the image before it publishes anything, and ci.yml publishes nothing, but both live on a branch that has reached neither main nor a tag. Until a v* tag is pushed, the by-hand tools/install-smoke.sh run is the only evidence an image installs.
  • The traffic archive has not been watched for a month. Its arithmetic, its restore and its interface cap are covered by tests and were measured against a stub router over minutes. A router whose interface names come and go for 31 days has not been observed.
  • UPnP is Wheelhouse's own, not the platform's. The pinned base has no service upnp configuration node and no miniupnpd package, so the agent answers UPnP and NAT-PMP itself and writes each mapping as a port forward and a firewall rule. It covers port mapping only: IPv6 pinholes are refused. See UPnP.

Shipped, but narrower than the name suggests#

The features below exist. Each is narrower than its name, so the boundary is stated here rather than found later.

The nameWhat is actually there
CAKE shapingEach interface — a VLAN included, though not a VLAN inside another — has an upload and a download rate, planned by the agent and applied by the Commit Bar. Upload is a CAKE policy on the interface's egress, with bandwidth, flow isolation, RTT, ack-filter, flow-isolation-nat and no-split-gso. The download takes either route this platform has: policing, a limiter on qos interface <if> ingress, or CAKE with the same settings through an IFB (interfaces input ifbN, a redirect, and the policy on the IFB's egress). The page says whether the kernel is running what the configuration asks for. delete interfaces input ifbN is never staged, and nothing is handed to the console: turning download shaping off leaves the IFB idle for the next use, because deleting it is a commit this base has been seen to fault on. No direct tc programming. DOCSIS and ATM overhead compensation are not omissions but platform gaps: there is no docsis, overhead, mpu or atm leaf under qos policy cake on this base
1:1 NATA mapping is a destination and source NAT rule pair, created, edited and removed as one row through the Commit Bar, numbered by the agent ahead of the port forwards and masquerade that would otherwise take its traffic. It is not written as nat static: committing that node through this base's HTTP API has been seen to stop the API process, so a nat static rule made elsewhere is listed read-only, and the agent refuses the node at every door that reaches a commit — /api/stage, /api/fleet/{id}/stage, /api/configure, /api/reconcile with apply=true, /api/commit, /api/fleet/{id}/configure and /api/fleet/{id}/commit, so a desired-state file carrying it fails loudly rather than committing — Built on VyOS
An OpenVPN instanceAdd instance builds a server, a client or one end of a site-to-site tunnel, with the certificates it needs from the router's own pki tree — named as they stand, minted by the agent, or pasted in and checked — or, for a site-to-site end, either a 2048-bit shared secret the agent mints and returns in the plan or certificates with the tls role the router needs, and the input firewall rule for its port when asked. Every field is edited afterwards, and a server's clients are added, revoked and given their .ovpn files from its settings. It configures one router, so the far end is a second visit
Offload flagsThe nine interfaces ethernet <if> offload leaves are staged from the interface detail panel, with what the kernel has on beside what the configuration asks for. A dash in the kernel column is not "off": the router's own command drops every feature the NIC has fixed, and rps/rfs are sysfs steering knobs ethtool never prints. Ring sizes, queue counts, link speed and duplex are console work
VRFA VRF is created, edited and deleted with its name, table, description and bound interfaces, through the agent's planner, and its static routes are edited with the Static routes form. Its routing table is shown for IPv4 only. A VRF's own BGP or OSPF, route leaking between VRFs and its VNI are not edited, and a VRF that has them keeps them. A read the router refuses is a note, never an empty table or a zero in a tile
A number on an app's cardA catalogue entry may declare a stats URL and a path to a single number in the JSON it answers with; the card shows that number and how old the reading is. Two of the catalogue's entries declare one. Wheelhouse never calls an app's own API with that app's credentials, and the health badge is still TCP plus an optional HTTP path
Uplink health monitoringThe router's verdict is VyOS' own — is the failover route in the forwarding table, and what does show wan-load-balance say. Beside it the agent probes each uplink itself, every five seconds, and shows per-target round-trip time, jitter and loss with its own verdict — and says per uplink whether the router would act on those numbers, which without a failover check or a load-balancer test is not at all
FleetA JSON file of routers, concurrent health, per-router configuration and version reads, and a per-router write plane: stage, review, un-stage, discard and commit, each against one router's own queue on the agent, reachable from the Fleet page. Fleet commits are audited as fleet-commit with the router id and the commands. A fleet commit can arm that router's own commit-confirm, confirmed on that router at /api/fleet/{id}/commit/confirm and nowhere else — the local /api/commit/confirm would let the armed router reboot while cancelling a window here — and audited as fleet-commit-confirm
Role-based accessFour roles — viewer, approver, operator, admin — enforced server-side on every route. Per-object permissions do not exist, and neither does a hardware-key second factor
Two-factorTOTP only — there is no hardware-key factor. Enrolment issues ten single-use recovery codes, shown exactly once; an admin can clear another account's factor, but not their own, and clearing one revokes that account's sessions without touching require_totp
A tamper-evident audit logEvery entry carries a sequence number and the hash of the entry before it, GET /api/audit/verify names the first entry that does not fit, and a configured collector gets each entry as it is written. Root on the box can still rewrite the file — a chain proves a break, it does not prevent one — and the export is off until you name a collector, so a router as shipped holds the only copy
Update awarenessThe router reads the release channel on a timer and the System page says when a newer version exists, with the notes checked against the checksum file published beside them. It installs nothing, and the check can be switched off
The desired-state fileIt mirrors the VyOS configuration tree node for node. It is not a simplified, product-shaped schema
Conntrack byte countersThey need nf_conntrack_acct enabled on the router. Without it they are absent

Commercially, what is not ready#

WhatWhere it stands
PricesSet, 2026-09-10, and on the product site. Nothing is sold under them until a licence agreement and terms of service exist
A licence agreement and terms of serviceDo not exist — The Wheelhouse licence
A support address, an issue tracker, a chat channelNone are public, and the source forge is private — Support
A security reporting addressNot published — Reporting a vulnerability
A release signing keyNone has been generated
The betaClosed and invite-only while the image is exercised on more than one kind of hardware. The terms, the seat count and how to apply have not been decided
The publisherNot established. No company, team, legal entity or location has been decided

Before each release#

Every release is driven in a browser against a live router before it is tagged. That is not the same bar as a hardware compatibility programme, a signed supply chain or a support contract.

See also#

Updated 2026-09-18 status roadmap