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
| Command | Syntax | Result |
|---|---|---|
clients / clients list | bare | List 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
- Web tab opens
ws://127.0.0.1:53219/wsand sends{ t: 'hello', clientId, label? }. - CLI looks
clientIdup in~/.tealstreet/trusted-clients.json. - Match found: handshake continues, CLI replies
welcome. - No match: the REPL prints a prompt with the
label,origin, and first few chars ofclientId, then blocks for operator input. - Approve: the client is appended to
trusted-clients.jsonand the handshake completes. Subsequent connections from the same tab are silent. - 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
}
]
}
| Field | Notes |
|---|---|
clientId | UUID generated by the web app per browser-tab namespace; max 64 chars. |
label | Optional human string from the hello frame. Shown in the approval prompt. |
origin | The browser-supplied origin header at connect time. |
approvedAt | Unix 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
| Situation | Action |
|---|---|
Browser profile rotated, old clientId is stale | clients revoke <prefix> (the entry is harmless but adds noise). |
| Public / shared machine no longer in your hands | clients revoke --all and shut down the listener. |
| Tab you don't recognise in the approval prompt | Deny at the prompt — nothing is persisted unless you approve. |
| Approved a tab you shouldn't have | clients 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.