跳到主要内容

Trusted clients

The trusted-clients allowlist is the double-consent gate that decides which web clients are allowed to drive the standalone CLI over the listener's WebSocket. Each browser tab generates a clientId UUID and presents it in its hello frame; the standalone CLI either recognises it from a prior approval or pauses the handshake and asks the operator at the REPL whether to allow the connection. Standalone-only — the web CLI doesn't need an allowlist of its own.


REPL commands

CommandSyntaxResult
clients / clients listbareList every approved client with id, label, origin, approvedAt.
clients revoke <id|prefix|--all>clients revoke <id|prefix|--all>Remove a client (or all). Prefix must be ≥ 8 chars; ambiguous prefixes return "Ambiguous".
clients
clients revoke 4f3a1c8e
clients revoke --all

A revoked client's next connection attempt is treated as a brand-new client — it will trigger another approval prompt at the REPL.


Approval flow

  1. Web tab opens ws://127.0.0.1:53219/ws and sends { t: 'hello', clientId, label? }.
  2. CLI looks clientId up in ~/.tealstreet/trusted-clients.json.
  3. Match found: handshake continues, CLI replies welcome.
  4. No match: the REPL prints a prompt with the label, origin, and first few chars of clientId, then blocks for operator input.
  5. Approve: the client is appended to trusted-clients.json and the handshake completes. Subsequent connections from the same tab are silent.
  6. Deny: CLI replies { t: 'rejected' } and closes the socket with code 4001. Nothing is persisted.

The full handshake — origin allowlist, hello shape, welcome payload, close codes — is documented in Listener → WebSocket handshake.


What gets stored

~/.tealstreet/trusted-clients.json:

{
"clients": [
{
"clientId": "4f3a1c8e-…",
"label": "Sam's laptop — Chrome",
"origin": "https://app.tealstreet.io",
"approvedAt": 1716045000000
}
]
}
FieldNotes
clientIdUUID generated by the web app per browser-tab namespace; max 64 chars.
labelOptional human string from the hello frame. Shown in the approval prompt.
originThe browser-supplied origin header at connect time.
approvedAtUnix ms timestamp of the operator approval.

The file does not contain any credentials — losing it just forces every client through the approval prompt again. Restore from backup or delete freely.


When to revoke

SituationAction
Browser profile rotated, old clientId is staleclients revoke <prefix> (the entry is harmless but adds noise).
Public / shared machine no longer in your handsclients revoke --all and shut down the listener.
Tab you don't recognise in the approval promptDeny at the prompt — nothing is persisted unless you approve.
Approved a tab you shouldn't haveclients revoke <prefix> immediately; the open WS is also dropped.

For the WS-level transport these clients ride on, see Listener. For the end-to-end pairing flow see Pairing.