Everything the identity layer adds
Eight things RustDesk does not do on its own. Each one is enforced server-side, in the path a connection actually takes — not as a preference the client can decline.
Sign-in before anything
A device cannot register, and a client cannot start a connection, until somebody is signed in.
Vanilla RustDesk is anonymous by design: a nine-digit ID and the server key are the whole story. TraceMote adds a require-login flag that gates the service's registration, the UI at startup, and both outbound connection entry points. With the flag off, every one of those paths is upstream's, unchanged.
- Gate on the service process, not just the window
- Both outbound entry points guarded, not only the obvious one
- Off by default — the unmodified path still exists, and still runs
- Signed-out clients are told why, in words a user can act on
Grants, per user, per device
Access is a grant with an owner, an expiry, and a list of what is allowed once connected.
A grant ties one user to one device. It can expire on its own, and it can carry limits that travel with the connection: thirteen per-connection permissions — keyboard, clipboard, file transfer, audio, recording, restart, and the rest — sent to the controlled device as part of the introduction, before a single frame is drawn.
- Optional expiry, enforced server-side
- Thirteen per-connection permissions, set per grant
- Limits ride the existing protocol field — no client patch
- Say nothing and the device keeps its own defaults
Revoke ends the session
Revoking access does not wait for the session to finish. It closes it, inside about three seconds.
There is deliberately no soft-revoke mode. Revoking a grant blocks the next connection and terminates any live one as a single action, over the heartbeat channel the client already runs — which means it works identically for direct peer-to-peer sessions and relayed ones, because it is enforced at the controlled endpoint rather than in the transport.
- ~3 s ceiling: the heartbeat runs every 3 s while a session is live
- Works on direct P2P sessions, which never touch the relay at all
- The user sees 'Closed manually by web console'
- One action — no revoke-then-remember-to-kick
A session log that can be read
Every authorization decision and every connection, correlated by an id minted at the moment of the decision.
The API mints an audit reference for each allowed connection; the rendezvous server carries it to the controlled device, and the client echoes it back on the connection and file-transfer logs it already sends. That one id is what turns a pile of events into a session you can open: who, which device, from where, how long, what was transferred.
- Who connected to what, when, and from which address
- File-transfer events on the same session record
- Filter by user, device, or date; drill into one session
- Decisions are logged even when the answer was no
Live sessions, and a way to end them
See what is connected right now. Close any of it from the browser.
The live view lists in-flight sessions with their owner, their target, and how long they have been open. Force-disconnect is one click, and it is the same mechanism as revocation — so the thing you tested is the thing that runs during an incident.
- Owner, target device, duration, transport
- Force-disconnect without revoking the grant
- Same code path as revoke — one mechanism to trust
- Latency is shown honestly in the UI, not hidden
Fail closed, with a way back in
If the permission API is unreachable, the answer is no — and there is still a documented way onto the box you would fix it from.
An outage denies connections rather than silently falling back to anonymous RustDesk. So that the outage does not also lock the operator out of the machine that would fix it, the rendezvous server accepts a pre-shared, signed, device-scoped, expiring capability that it can verify with a public key alone. Every use of it is logged locally first and reconciled when the backend returns.
- No silent bypass for ordinary users, ever
- Break-glass is signed and scoped to one device, with an expiry
- Its audit record is written locally first — the backend is down, after all
- The console shows an unmissable banner while one is unexpired
Both chokepoints, not the obvious one
The relay request is authorized in its own right. Gating only the punch-hole path would have been decoration.
A relay request reaches the named peer without passing through the punch-hole handler at all, so gating that one path would have left the other wide open. Both are authorized here, and a decision cache keeps an ordinary connection to a single decision.
- Punch-hole and relay signalling both authorized
- One connection, one decision — the client retries three times
- Refusals that were going to fail anyway cost zero API calls
- The relay itself stays unmodified: one enforcement point, not two
Your build, your defaults
Server, relay, key, API and the login requirement, baked into the installer you hand out.
Nobody types a rendezvous address. The release pipeline signs a config with your own key and ships it inside the bundle, so a freshly installed client already points at your infrastructure with login required. The app name, icons and identifiers are yours too.
- Rendezvous, relay, API and key preconfigured
- require-login on from the first launch
- Your own signing key — the trust anchor is a build input
- The update channel is yours, or off
Thirteen things a grant can decide
Set on the grant, carried with the introduction, applied by the controlled device. Leave one unset and the device keeps its own answer — a limit you did not ask for is not silently invented.
Where a connection is allowed or refused
Once, during the introduction, before the two devices have spoken to each other.
Allow. The two peers are introduced, the grant’s permission set travels with the introduction, and an audit reference ties every later event to this one session.
Deny. No introduction happens, and the reason is shown to the person verbatim — “Please sign in to connect to this device.” — rather than a timeout they will file a ticket about.
See it refuse something
The fastest way to trust an authorization layer is to watch it say no. We will stand a deployment up for you, or you can run one yourself in an afternoon.