Security → Architecture
Security architecture
TunnelCrib has four components. Only two of them ever see Service traffic; the Central Server only ever sees control-plane and signaling messages.
| Component | Role | Sees Service traffic? |
|---|---|---|
| TunnelCrib Client | Requests a Tunnel, opens a local listener, forwards Service traffic to the Agent. | Yes (it is one endpoint of the Tunnel) |
| Central Server | Authenticates Devices, enforces organization isolation, allocates sessions, relays signaling messages. | No — signaling only |
| TunnelCrib Agent | Advertises approved Services, serves the requested Service over the established transport. | Yes (it is the other endpoint) |
TunnelCrib Relay (tunnelcrib-bridge) | Optional data-plane hop, used only when a Direct Tunnel cannot be established. | See What the Relay can see |
Direct Tunnel first, Relay only on failure
Every Tunnel attempt tries a direct Client–Agent path before ever involving a Relay, using three fallback tiers:
| Tier | Mechanism | Falls back when |
|---|---|---|
| 0 | UDP + KCP, local/VPN candidates and STUN-assisted NAT traversal | No reachable candidate or punch timeout |
| 1 | TCP simultaneous-open punch (SO_REUSEPORT) | Tier 0 fails within the shared punch budget |
| 2 | TunnelCrib Relay (tunnelcrib-bridge), hosted or a Private Relay | Tier 1 also fails within the total punch budget (10s) |
Whichever tier wins, SSH is the only authentication and encryption layer. UDP and TCP punching only establish the underlying byte stream; the SSH handshake, host-key pinning, and public-key authentication are identical in every tier.
Registration and authorization sequence
- TunnelCrib Client, TunnelCrib Agent, and a customer Private Relay each register with the Central Server (
hostname,uuid, and, for Agents, advertisedprotocols). - The Central Server validates each Device against the organization's registry by organization, UUID, and Device type.
- The Central Server issues a nonce challenge to both peers.
- Client, Agent, and customer Private Relay sign the nonce with their registered per-Device identity key (see Device identity).
- The Central Server verifies the signature against the registered public key. Connections failing this check are rejected.
- When a Client requests a Tunnel, the Central Server checks the requested protocol against the Agent's advertised list and organization boundary before signaling either peer.
Independently of the registration handshake, every Direct Tunnel's SSH layer separately pins a per-session Client public key and, after first use, the Agent's host key — so a Direct Tunnel cannot be impersonated even if the transport-level address exchange were spoofed. Address candidates do not grant access to a Service; the Central Server still authorizes the requested Agent and Service before signaling begins.
Signed control messages
Registration proves possession of a Device key. After registration, TunnelCrib adds message-level signatures to the WebSocket control plane so a valid connection cannot simply be used to inject or replay commands.
| Direction | Control | Protection |
|---|---|---|
| Client → Central Server | Requests, tunnel signals, and status messages | Client ECDSA P-256 key signs each JSON payload with the Device UUID, connection session ID, and increasing sequence number. |
| Agent → Central Server | Agent control messages and tunnel signals | Agent ECDSA P-256 key signs each JSON payload with the same identity, session, and sequence binding. |
| Private Relay → Central Server | Registration and relay control connection | The registered Private Relay signs the nonce challenge. Its ongoing control messages are currently accepted unsigned for compatibility while relay signing support is being completed. |
| Central Server → Agent | Managed tunnel configuration and sensitive tunnel commands | The server signs the payload with its active P-256 control-server key. The Agent verifies the pinned server key ID, organization, target Agent UUID, and increasing sequence number before processing it. |
Registration and nonce-response messages remain bootstrap messages and are not wrapped in the per-message envelope. During rollout, the server can accept older unsigned Client or Agent messages in compatibility mode; deployments can switch to required signatures after all participating Devices support them. A shared infrastructure Relay has no registered Device key and is not part of this message-signature policy.
Control-server signing key
The Central Server's signing key is an unencrypted ECDSA P-256 private key loaded from a protected server secret. The private key is never sent to Devices and is not stored in the management database. The server publishes only the corresponding OpenSSH public key and key ID during registration. Devices pin that key in their local organization configuration, and every server-signed command is bound to the organization, target Agent, key ID, payload, and per-connection sequence. A key rotation therefore requires issuing and pinning a new key ID before commands signed by it are accepted.
Last reviewed 2026-10-22.