Opening RDP or SSH to a machine at the office usually means a public IP and open ports, a company-wide VPN, or a pile of jump hosts.
We wanted something narrower: access to a service, not to the whole network — with roles, an audit trail, and a way to invite an external contractor without handing them the connector token.
That product is 2GC Tunnel (CloudBridge).
The problem
- Port forwarding never stays temporary.
- A full VPN is overkill when someone only needs one box over RDP.
- Sharing access with a service partner often means sharing the tunnel token — which is full control of that tunnel.
Goals:
- No inbound ports on the customer network.
- Per-server grants (
view/manage), not “everyone on the VPN”. - Contractors as a separate organization, view-only on selected servers.
- A desktop app that connects in one click after sign-in.
What users see
Dashboard. Create a server — Cloudflare Tunnel and DNS are created for you. Add RDP, SSH, gRPC or HTTP; each service gets a hostname like rdp-office.your-domain. Install cloudflared once with the connector token from the UI.
Access. Owners and admins invite members, use groups, and grant view or manage per server. A server you cannot see returns 404.
Contractors. An external company is its own org. Both sides confirm the link; you open specific servers for view only — no connector token, no admin of your org.
Desktop app. Sign in (Clerk in the browser, or a personal access token). Pick a server, press Connect — Remote Desktop or a terminal opens against a local forward. Tokens live in the OS keychain; only a hash is stored on the server.
Architecture
| Layer | Choice |
|---|---|
| Edge app | Cloudflare Worker, TypeScript, server-rendered HTML |
| Data | D1: orgs, users, groups, servers, services, grants, API tokens |
| Auth | Clerk session; Worker verifies JWT locally |
| Tunnels / DNS / Access | Cloudflare REST API |
| Desktop | Tauri 2 (React + Rust), personal tokens |
| Secrets | Cloudflare Secrets Store |
Deleting a server tears down Access apps (if any), DNS, and the tunnel, then the D1 row. If Cloudflare fails mid-delete, we keep the row so you can retry.
Desktop Clerk sign-in uses a loopback callback: confirm in the browser, token goes only to 127.0.0.1.
Security choices
- Outgoing only —
cloudflareddials out; no inbound holes for the world. - Optional Cloudflare Access in front of SSH/RDP.
-
manageincludes the connector token — treat it like root for that tunnel. - CSRF on every state-changing POST; CSP without inline scripts in the cabinet.
- API tokens shown once, stored as SHA-256, recent re-auth to mint a new one.
This is not a full Zero Trust program by itself. It is tunnels + tenancy + grants + a client.
What’s next: Zero Trust IdPs
Today cabinet auth is Clerk; Access in front of SSH/RDP is optional. Next we make Cloudflare Zero Trust / Access a first-class gate so each RDP/SSH connection authenticates with an IdP you already use.
Planned providers (Cloudflare Access IdPs):
- Microsoft Entra ID (Azure AD)
- Okta, Google, GitHub, OneLogin, PingOne, Centrify
- LinkedIn, Facebook, Yandex
- OIDC and SAML
Also: signed macOS/Windows builds, Access defaults for new servers, contractor UX.
If you try this with a real contractor org, tell us where the model breaks — that is the part we care about most.
Product: https://2gc.dev



