Skip to content

Scope the Punchd gateway list to this deployment, and split status from VPN - #56

Merged
sashyo merged 3 commits into
mainfrom
feat/strict-gateway-tenancy
Aug 13, 2026
Merged

sashyo merged 3 commits into
mainfrom
feat/strict-gateway-tenancy

Conversation

@sashyo

@sashyo sashyo commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Yes, that's right — the Punchd list should be scoped to the deployment exactly like the dashboard, and it wasn't quite.

The tolerance had to go

Both surfaces treated "reports no issuer" as show everywhere. That was deliberate, so a staggered rollout wouldn't blank a console mid-upgrade — but it is precisely the cross-tenant leakage the issuer was introduced to stop. It's why devops still lists Sasha-Gateway, gateway-vf28pg and gateway-z3pz71.

Now strict on both: a gateway must report an issuer, and it must match this deployment's.

The rule also moves into a single shared belongsToTenant, replacing two near-identical copies that could drift — one in the dashboard aggregation, one in the admin discovery listing.

What disappears

The four gateways still on old binaries report no issuer, so they vanish from every console until updated:

Demo-Gateway     keylessh-rdp        (being decommissioned)
Sasha-Gateway    DESKTOP-DFL00QK
gateway-vf28pg   proliant
gateway-z3pz71   Proliant2022

That's the intended trade — showing them on consoles they don't belong to was worse than showing them nowhere — but it does mean the Proliant and desktop gateways drop off demo until their binaries are updated. If you use them day to day, update those hosts before merging this.

The three container gateways all report issuers and are unaffected:

Devops-GW   → https://login.dauth.me/realms/keylessh-devops
Staging-GW  → https://staging.dauth.me/realms/keylessh-staging
Tide-GW     → https://login.dauth.me/realms/keylessh-demo

tidecloak.json in Manage

The paste field was already there — it just looked empty, because a gateway never reports its TideCloak config and never can: that's the trust anchor, unpushable by design, and the signal server relaying gateway data has no business holding it.

What was missing is any way to see which TideCloak a self-registered gateway actually trusts. The Manage dialog now shows the reported issuer read-only, above the paste field, with a note explaining why the file itself isn't there. Paste one in and the console can generate tidecloak.json for that gateway as usual.

Testing

26 discovery tests (5 new on the strict rule: exact match, different realm on the same host, same realm on a different host, trailing-slash and case tolerance, and the no-issuer rejection). Full suite green, tsc clean apart from the errors already on main.

sashyo added 2 commits August 13, 2026 15:10
A gateway that reported no issuer was shown on every console. That tolerance
existed so a staggered rollout would not blank anyone's list, but it is the
cross-tenant leakage the issuer was added to prevent — devops listing demo and
staging gateways was the original complaint.

Now strict on both surfaces: a gateway must report an issuer and it must match.
The rule moves into one shared belongsToTenant so the dashboard and the Punchd
list cannot drift apart, replacing two near-identical copies.

Gateways still on old binaries report no issuer and so disappear from every
console until they are updated. That is the intended trade — showing them
everywhere was worse than showing them nowhere.

Also surfaces the issuer a gateway reports in its Manage dialog. The
tidecloak.json itself is never reported and never pushable, so this is the only
way to see which TideCloak a self-registered gateway actually trusts.
Discovered gateways showed Online/Offline in the column headed VPN, so a
gateway with VPN disabled read as "VPN: Online". Two unrelated facts sharing
one cell.

Status now has its own column, and it covers every row rather than only
discovered ones — a stored record means a gateway is configured, not that it
is connected, and which of those is true is what an admin actually wants to
see. The VPN column shows On/Off for adopted gateways and an em dash for
discovered ones, where it is unknown rather than off.
@sashyo sashyo changed the title Scope the Punchd gateway list to this deployment's issuer Scope the Punchd gateway list to this deployment, and split status from VPN Aug 13, 2026
The editor derived its rows from the serialized backends string on every
render. A half-filled row cannot be represented in that string — serializing
drops rows without both a name and a URL — so a new blank row was discarded
before it could be rendered and the button appeared dead.

Rows now live in the editor. The string is still what gets saved: every edit
serializes the complete rows back out, so incomplete rows are excluded from
what is stored while staying on screen to be filled in.

Extracted to its own component, which is where it belonged, and which lets it
be tested without pulling the whole admin page and its TideCloak and
react-query dependencies into the test.

The tests fail against the previous implementation — four of the seven — so
they pin the actual defect rather than the fix.
@sashyo
sashyo merged commit ae752e6 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