1 PairingNothing joins without your yes
A cloud agent posts its repository, branch and runner and gets a six-character code. agent-relay remote approve asks [y/N] and names the checkout. Requests expire after ten minutes, at most five wait, and --yes approves one named code only.
2 ScopeOne room, one identity
The room comes from the token, never from the request. The first registration binds the token to one agent id, and the gateway imposes it after that. A cloud agent cannot take over a local identity or send as one.
3 TokensHashed, expiring, revocable
256-bit random values, stored only as SHA-256 hashes and compared in constant time. A paired session lasts 24 hours; an always-on token expires after its window goes unused. remote revoke drops a token at once, and a revocation sticks.
4 AllowlistCoordination only, no local paths
Register, send, inbox, ack, claim, tasks, branches, handoffs and the rest of the coordination set pass. Everything else is refused by name. A request carrying a local path is refused, and no response names one: the room reads as ..
5 LimitsRate limited and audited
Per token and per address, before the token is looked up, with 429 and Retry-After. A token holds four long polls at most. The audit log records token id, runner, room, operation and result, never a token value.
6 Off switchClosed in one command
agent-relay remote off stops the tunnel and the gateway and drops any dashboard link. With Cloudflare, --access adds an Access service token, so the URL alone is not enough to reach the gateway.