Wheelhouse docs

Reporting a vulnerability#

If you have found a security flaw in the agent, the web UI, the installer, the packaging or the release pipeline, this page is where it goes and what happens next. It is the policy in SECURITY.md, stated for the web. Two things are worth knowing before you read on: the reporting address has not been published yet, and a security report does not go to support.

EmailNot published yet — <TODO: owner>. It will appear on the product site's security page
PGP keyThere is none. Until there is, keep anything that would be damaging in transit out of the report: say that you have it, and a way to send it will be arranged
Public issue trackerThere is none, and the source forge is private. Do not look for one

If you have had no acknowledgement in three business days, assume the mail went astray and send it again.

What to include#

You do not need all of this. Send what you have.

  • The version. dpkg-query -W -f='${Version}\n' wheelhouse-agent on the router, or the version on the console banner. If it matters which base you are on, cat /etc/os-release.
  • Which component: the agent, the web UI, the installer, the packaging, the ISO build, or the licence server.
  • What an attacker can do, and what they need first — network position, credentials, a role, physical access.
  • Steps to reproduce. A curl command against wheelhouse-agent --demo is ideal, because it needs no router at all — agent/main.go registers --demo as "start without VyOS credentials".
  • Whether you have told anyone else, and whether you have a disclosure date in mind.

What Wheelhouse commits to#

Acknowledge your report3 business days
Say whether we agree it is a vulnerability, and its severity10 business days
Ship a fix, or give you a dated plan90 days from the acknowledgement
Credit you in the changelog, if you want itwith the fix

These are the windows for a small team, stated so you can hold them to it rather than guess. If something is being actively exploited, say so in the subject line.

Which versions get fixes#

VersionSupported
The most recent releaseYes
Anything olderNo

There is no long-term-support line and no backporting. Fixes go into the next release, so how quickly you plan to upgrade is part of your own risk position.

A fix reaches you as a new release on the download host, with the security-relevant changes in that version's Security section of CHANGELOG.md. There is no advisory feed and no notification mechanism on the router — nothing in the agent reads the release channel, so watching the download host is the only way to learn that a release exists. That is a gap, not a design.

Scope#

In scope — the parts Wheelhouse writes:

  • agent/ — the Go control plane: authentication, authorisation, the API, TLS, the licence gate, the desired-state loop, the app catalogue handling.
  • ui/ — the web UI.
  • packaging/ — the .deb, the systemd units, the first-boot script, the console banner, the installer and its unattended path.
  • tools/ — the OPNsense importer and the seed builder.
  • The release pipeline and the published artefacts.

Out of scope here, but still worth telling us about:

  • VyOS, the Linux kernel, FRR, Kea, pdns-recursor, nftables, strongSwan, OpenVPN, Suricata, Podman and every other Debian package in the image. These are upstream and unmodified; report them to their own projects. If a Wheelhouse image ships a version with a known vulnerability, that is ours — tell us, and it becomes a question of when a new image goes out.
  • Anything that requires root on the router, or physical access to it. Both are outside the threat model and docs/security.md says so plainly.
  • A finding already on the known-gaps list. We know. Telling us how bad it actually is, with a working demonstration, is still useful.
  • Scanner output with nothing behind it: a header absent by design, a TLS suite you would prefer, a version number in a banner. It will be read, and the question will be what an attacker does with it.

Safe harbour#

Research done in good faith against your own installation is welcome and will not be pursued. That means your own hardware or VM, no access to anyone else's data, no denial of service against shared infrastructure, no social engineering of people, and the windows above before going public.

The licence server and the download host are live services other people depend on. Report what you find; do not test destructively against them.

What is not offered#

  • No bug bounty. There is no money. There is credit in the changelog, a reply from a person who read the report, and a fix.
  • No CVE assignment. Wheelhouse is not a CNA. If you want a CVE, request one and the details will be confirmed.
  • No embargo longer than 90 days without a specific reason you agree with.

The gaps already known#

Listed by the product about itself, so a review finds them from us first — docs/security.md "Known gaps". Among them:

  • Releases are not signed. SHA256SUMS is signed only when a release key is configured in the build environment, and no key exists yet — so nothing published so far carries a signature, and a checksum proves the download survived the network, nothing more — .forgejo/workflows/publish.sh.
  • The audit log is not tamper-evident. It is an append-only file of JSON lines (/config/wheelhouse/audit.jsonl, mode 0600) with no hash chain and no sequence numbers, and there is no way to ship it to a syslog collector or a SIEM. Root on the box can rewrite it invisibly.
  • The agent binds every interface (0.0.0.0:8443), so the firewall is the only thing keeping the management UI off the WAN, and there is no listen-address setting short of editing the unit file.
  • GET /api/oidc/status discloses the issuer URL unauthenticated, undoing what the login screen's own probe withholds.
  • No admin reset for two-factor, and no recovery codes. Losing an enrolled device means console access and a hand-edited state.json.
  • No factory reset and no rescue boot entry.
  • Secrets are redacted by leaf name, so a value that is a secret because of where it sits — a container environment variable, an SNMP community string — is not matched below the admin role.

See also#

Checked against#

SECURITY.md · docs/security.md · docs/upgrade.md · CHANGELOG.md · agent/main.go · .forgejo/workflows/publish.sh

Updated 2026-09-02 security disclosure legal