Skip to content

Punchd: self-registering gateways and an installer that takes your config files - #53

Merged
sashyo merged 2 commits into
mainfrom
feat/gateway-installer-wizard
Aug 13, 2026
Merged

sashyo merged 2 commits into
mainfrom
feat/gateway-installer-wizard

Conversation

@sashyo

@sashyo sashyo commented Aug 13, 2026 •

Copy link
Copy Markdown
Owner

Two changes to how a Punchd gateway gets set up and managed. Both attack the same friction: a gateway you stand up is not manageable until you hand-carry config to it, or hand-retype config about it.


1. Self-registered gateways appear in the console

A gateway that registers with a signal server is live and usable, but Punchd → Gateways listed only hand-created records — so proliant, Proliant2022 and Sasha-Gateway are running and invisible there. To manage one you had to retype what the gateway already knew.

Now live gateways are listed alongside stored ones, marked Self-registered, showing the settings they report. Editing one adopts it — creating the record — so there's no separate "add" step.

The part that needed care

Seeding a record from signal server data alone would leave ports, TLS and server URL unknown, because the signal server never sees them. The first save would then push those blanks over a working gateway's config.

So the gateway reports its own editable settings at registration, and adoption seeds from that:

  • It reports exactly the fields the console may push back — a test asserts that set never drifts from PROTECTED_FIELDS, so the console can't show a setting a push would silently refuse.
  • It never reports api_secret, turn_secret or the TideCloak config. Those aren't pushable, and the signal server relaying this has no business holding them. Tested by asserting the serialized payload contains none of the secret values.
  • adoptionRecord omits anything the gateway didn't report rather than defaulting it, so adoption can't invent a value a later push writes back.
  • The edit is merged over the reported values, so untouched settings keep the gateway's real ones.
  • Adoption re-checks for an existing record, in case two admins adopt the same gateway at once.

Discovered gateways are filtered by issuer like the dashboard, so they only show on their own tenant's console.


2. Installer wizard takes gateway.toml and tidecloak.json

The MSI installed the service and then told you to copy both files in yourself — the old exit page read "Copy your gateway.toml and tidecloak.json to C:\ProgramData\punchd-gateway then restart the service." Every fresh install needed a manual second step.

A Configuration files page now sits between Welcome and Install, with a Browse button for each:

  • Both optional — cancelling a file dialog is a normal outcome, not an install failure.
  • Wrong-file detection — each is checked for the fields that identify it (gateway_id; realm + auth-server-url), so picking the JSON in the TOML slot is caught with a pointer to where the right one comes from.
  • Unattended installs keep working: msiexec /i PunchdGateway.msi /qn GATEWAY_TOML_FILE="..." TIDECLOAK_JSON_FILE="...".
  • Files land before InstallFinalize, so the service's first start sees its config.
  • Uninstall removes only the two files it placed.

Custom actions follow the existing VPN installer's pattern; the CA compile step reuses the vswhere lookup rather than a hardcoded Visual Studio path.


Testing

315 TypeScript tests (21 new on discovery/adoption) and 59 Rust tests (5 new on reported config) pass. tsc --noEmit shows only the errors already on main.

The MSI is not verified. WiX only runs on Windows — on Linux it prints The WiX Toolset only supports Windows... All behavior after this point is undefined and fails on path separators. I confirmed the XML parses and every cross-reference resolves (custom action IDs, DoAction targets, dialog navigation), and that the workflow YAML sequences the new MSVC step before Build MSI. The C custom actions have never been compiled. Worth a careful first install on a throwaway box.

Depends on #52

build-gateway-windows currently fails on the vendored OpenSSL build before reaching any of this, so #52 has to merge first or the job still produces no MSI.

sashyo added 2 commits August 13, 2026 14:06
The gateway MSI installed the service and then told you to copy both config
files into ProgramData yourself, so a fresh install always needed a second,
manual step before the gateway could do anything.

Adds a configuration page to the wizard with a Browse button for each file.
Both stay optional — an admin who has not generated them yet can install now
and add them later — and each is checked for the fields that distinguish it,
so picking the wrong file of the two is caught rather than silently installed.
The same paths can be passed on the command line for unattended installs.

Custom actions follow the existing VPN installer's pattern, and the CA build
uses the same vswhere lookup as the VPN MSI job.
A gateway that registers with a signal server was live and usable but
invisible in Punchd → Gateways, which listed only hand-created records. To
manage one you had to retype what the gateway already knew.

Gateways now report their own editable settings at registration, the console
lists live gateways alongside stored ones marked "self-registered", and a
record is created the first time one is edited.

Reporting the settings is what makes adoption safe. Seeded from signal server
data alone, ports and TLS would be unknown, and the first save would push
those blanks over a working config. The gateway reports exactly the fields the
console may push back — a test asserts that set matches PROTECTED_FIELDS — and
never api_secret, turn_secret or the TideCloak config.

Adoption also merges the edit over the reported values, so untouched settings
keep the gateway's real ones, and it re-checks for an existing record in case
two admins adopt the same gateway at once.
@sashyo sashyo changed the title Installer wizard: pick gateway.toml and tidecloak.json during setup Punchd: self-registering gateways and an installer that takes your config files Aug 13, 2026
@sashyo
sashyo merged commit 33b3747 into main Aug 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant