Files
UNITRONIX abc00b8804 feat(guest): enforce scoped guest access lifecycle
Bind guest WebSocket sessions to a single target peer, enforce grant lifecycle and atomic usage, add the guest issuer scope, and document the password-less security boundary.\n\nRefs #440\n\nThanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
2026-10-03 10:22:20 +02:00

3.1 KiB

Guest Access Links

Guest Access Links provide temporary Web Remote access without creating a BetterDesk Console account for the recipient.

Security model

  • A link is an opaque, time-limited grant. The raw token is returned only when the link is created; the server stores only its hash.
  • Every WebSocket upgrade must include the selected peer_id and a guest_session value. BetterDesk validates both the token and the peer allowlist before opening the bridge.
  • The rendezvous bridge checks PunchHoleRequest and RequestRelay targets server-side. Changing the URL or sending a different protobuf target cannot escape the grant.
  • TTL and revocation apply to active bridges. The panel closes locally revoked bridges immediately and periodically revalidates grants for revocations made by another panel process.
  • max_uses is consumed atomically after the first valid session-opening protocol message. Failed upgrades do not consume a use.
  • Guest session open/close events contain grant ID, peer, transport, source IP, duration and close reason. Tokens and passwords are never written to audit records.

For customer self-service, create a grant containing one peer. Existing operator-created grants may still contain multiple peers, but each individual WebSocket remains bound to one selected peer.

Password-less access

The organization peer vault (#367) encrypts unattended passwords at rest and is available to authorized operators. Guest grants do not contain passwords and public guest endpoints never return vault plaintext.

The current RustDesk Web Remote protocol performs the password challenge and hash calculation in the browser. Therefore, simply attaching a vault reference to a grant would either expose the password to the browser or require a protocol-aware proxy that terminates part of the end-to-end handshake. The second option needs a separate design and security review before it can be enabled for customer links.

Until that design is approved, guests must complete the normal target-device password or approval handshake.

The guest_issuer role has only:

  • device.view
  • guest.create

Use device and organization scoping to restrict which peer IDs the issuer may select. It does not grant general device.connect or Console administration.

The panel endpoints are:

  • POST /api/guest/access-links
  • GET /api/guest/access-links
  • DELETE /api/guest/access-links/:id

Troubleshooting 403 responses

Check the response from the panel's GET /api/guest/access-links/peers?token=... first. It must return valid: true. Then verify:

  1. The link has not expired or been revoked.
  2. The URL still contains the complete token.
  3. The selected peer is in peer_ids.
  4. The panel can reach the Go API and has the current API key.
  5. For split-container or reverse-proxy deployments, PANEL_SIGNAL_PROXY_CIDRS contains the panel-to-signal source network.

The WebSocket URLs generated by the current client include guest, peer_id, and guest_session on both rendezvous and relay connections.