Start with the threat model, not the encryption badge
“Encrypted” is necessary, but it is not a complete security claim. A practical terminal threat model asks who can invoke the MCP tools, whether a stolen token can be replayed against another resource, how a machine becomes paired, whether a local service is reachable from the LAN, what the relay can observe, and what privilege the resulting command inherits.
The highest-impact failures are usually authorization failures or excessive local privilege, not the absence of a decorative lock icon. A secure design needs a control at every hop.
HTTP MCP authorization: bind tokens to the intended resource
The Model Context Protocol authorization specification uses OAuth-style protected-resource discovery for HTTP transports. It requires access tokens in the Authorization header and requires resource servers to validate tokens before serving protected requests.
A particularly important requirement is audience binding: tokens should be intended for the MCP resource that receives them. The specification also explicitly warns against token passthrough because passing a client token through to unrelated downstream services can create a confused-deputy problem.
For a terminal service, that means the public MCP endpoint should authenticate requests as its own protected resource. A device credential used by the local service is a separate trust relationship; it should not simply be the ChatGPT-side bearer token forwarded down the stack.
Reference: MCP Authorization specification.
Device pairing is a second authentication boundary
Even a correctly authenticated ChatGPT-side request should not be allowed to select an arbitrary computer. The device needs its own identity and credential, established through an explicit pairing flow.
TerminaLink’s local service creates a device identity, starts a pairing request, and presents a browser approval flow containing the device name, platform, architecture, and pairing code. Once approved, the local service receives a device credential used to authenticate its outbound connection to the relay.
The relay stores the device credential in a verifiable hashed form rather than storing a plaintext copy for later retrieval. The local machine retains the credential required to reconnect. If that credential is suspected to be exposed, revoke the device and pair again.
Keep the local MCP server local
The cleanest local boundary is loopback. TerminaLink’s local MCP endpoint binds to 127.0.0.1, not to a LAN or public interface, and it is protected with a newly generated bearer token for each local-service run. The outbound local service is the component that bridges that local endpoint to the remote service.
This is materially different from exposing a local MCP server on 0.0.0.0 and relying on the router to save you. Loopback reduces accidental network exposure and keeps the local MCP interface inside the machine.
TLS is not the same as application-layer end-to-end encryption
TerminaLink’s hosted architecture requires HTTPS for its public relay and uses secure WebSocket transport when the relay URL is HTTPS. That protects traffic from passive network observers between endpoints and the relay.
It is still important to state the boundary precisely: the relay terminates the connection and proxies MCP payloads. The current design is not opaque application-layer end-to-end encryption where only ChatGPT and the local service can decrypt command content. The service must therefore be operated as a trusted processing boundary.
For that reason, data minimization matters. The service is designed to proxy command and output data without intentionally keeping it as a persistent server-side command log.
Least privilege has to continue onto the development machine
Authenticated requests still pass through the local security policy. Project execution defaults to the selected workspace sandbox. Host Observation and full system access are separate paths with different permissions.
Run the local service as a standard user. Keep production credentials outside the selected workspace and local service account where possible. The sandbox uses native controls; Docker and a separate coding harness are not user requirements. Full system access remains a deliberate higher-access choice, and completed host changes are not undone by expiry.
Revocation and deletion are part of security, not account housekeeping
Long-lived device access needs an exit path. TerminaLink’s relay includes authenticated device-revocation and account-deletion endpoints so a paired device can be invalidated instead of relying on “just uninstall it.” The local CLI is designed to clear the device credential when access is revoked.
Revocation should be used after a lost machine, suspected credential exposure, or whenever the trust relationship no longer makes sense. Uninstalling a local executable without revoking its server-side credential is weaker than doing both.
Security review checklist
- Public MCP endpoint requires authenticated access.
- Tokens are validated for the intended resource; they are not blindly passed downstream.
- Device pairing requires an explicit approval step.
- Local service authenticates its outbound connection separately.
- Local MCP binds to loopback, not the LAN.
- Transport to the hosted relay uses HTTPS/WSS.
- Server-side command/output persistence is minimized and documented.
- The local service runs under a deliberately chosen OS account.
- Verify command, output, session, and native resource limits independently.
- Verify sandbox rejection, explicit full system access approval, expiry, and platform-specific enforcement.
- Device revocation and account deletion exist and are testable.
See the product-specific TerminaLink security model for the exact current boundary.