Vault Manager v0.7.5
Vault Manager v0.7.5
Owner-signed hApp updates: a computer that owns your node can push an app update without a pairing
code. If you owned your node from this computer and tried to update an app, the push could fail with
"owner pairing required: enter the code shown on the node's screen" — a screen a headless node does
not have. That dead end is gone.
What was wrong
Uploading a new app version to your node (POST /happ) insisted on a pairing secret first — a
credential the node only hands to a computer with an active management pairing. A computer that
genuinely owns the node but had no live pairing (for example, one that redeemed an owner code after
its saved credentials were lost) could sign a request with its own key, but Vault Manager stopped
before sending it, because it could not first mint that secret. The node's stock refusal then told
the owner to read a code off the node's console — which, on the headless boxes these nodes usually
run on, does not exist.
Mark ruled it plainly (2026-08-22/23): any computer that holds owner on a node may push app updates
— the same standing as re-enrolling the app, and no pairing ceremony required.
The fix
Vault Manager already signs every upload with this computer's key. It now sends that signed request
even when it cannot mint a pairing secret, so a computer that owns the node is no longer stopped
before it can try:
- The pairing secret is now best-effort. It rides along when the node gives us one (older nodes still
gate on it), but its absence no longer aborts an owner-signed push. - Every push carries the signed challenge unconditionally — the exact shape the node already accepts
for reinstalls. A node that honours owner-signed pushes accepts it on the signature alone. - Nothing changes for a fully-paired computer: it still sends the secret and the owner token
alongside the signature, exactly as before.
And the error, when a push is refused, no longer sends a headless-node owner hunting for a console
code. On the update path it now says the truth: this refusal means the node's own software predates
owner-signed pushes — update the node's software (Manage node → "Update the node software") and try
again. Nothing to type, nothing to read off a screen the node does not have.
This is the client half of a two-part fix. The matching node change (vault-node, which makes
POST /happ accept an owner-signed request and rewrites the same refusal at its source) is committed
in that project; the end-to-end push against a live node is verified once both halves are on the same
node.
Verification
- 222 unit tests, including the two new ones for this fix: the update-path refusal is turned into
"update the node's software" and never into a console-code instruction, and an unrecognised error is
passed through untouched. The explainer guard was checked by asserting the old dead-end wording can
never reappear (nopair_code, nocat …, and the screen the stock error names is explicitly
denied). - The client's signing convention was confirmed against the node's own committed contract, not
assumed: the node accepts a §4 signed challenge at manage scope signed over the .happ bytes, same
auth as/happ/reinstall— which is exactly what this build sends. - Clean-room launch cert: the published installer, downloaded anonymously, was installed and
launched inside a fresh Windows Sandbox (a pristine Windows 11 VM with no build tools) — the app
rendered its full UI, not a blank window. This is the launch that a machine which can build the app
can never honestly perform for a customer.
The fully paired update path is byte-for-byte unchanged; only a computer that could sign but not mint a
pairing secret behaves differently — and it went from "stopped before it tried" to "sends an
owner-signed push", which is strictly better.
Downloads
Published under both VaultManager-* and VaultFlasher-* names; the bytes are identical.
NSIS setup.exe sha256 75ab43df8c268683c7f11f169ef3028ad68367cba569e7c6a435e1b8de22ff30
MSI sha256 2ff9b51e2f3fac49659d5223c4ac4bcac50d6ac68b20ab9273bf810ae3867a53