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

76 lines
3.1 KiB
Markdown

# 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.
## Issuing links with a restricted API identity
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.