Cloudflare Zero Trust connection manager for Windows, Linux, and macOS
TunnelDesk is a desktop application that lets you manage Cloudflare Access tunnels, direct SSH, RDP, Telnet, and HTTP connections from a single interface. Credentials are encrypted at rest with the platform keychain. Enterprise deployments support Entra ID sign-in, Group Policy, and org config sync.
Disclaimer: TunnelDesk is an independent, open-source project and is not affiliated with, endorsed by, or sponsored by Cloudflare, Inc. "Cloudflare", "Cloudflare Zero Trust", and "Cloudflare Access" are trademarks of Cloudflare, Inc.
- Cloudflare Access tunnels — RDP, SSH, Telnet, and HTTP/HTTPS connections routed through Cloudflare Zero Trust via
cloudflared. No VPN, no open firewall ports. - Direct connections — SSH, RDP, and Telnet without a tunnel when you are already on the right network.
- HTTP/HTTPS — open in your default browser from the connection sidebar.
- Embedded terminal powered by xterm.js with a Windows Terminal-style tab bar.
- OS and Linux distro icons per tab, detected live from the remote host.
- Search, resize, and full UTF-8 support including box-drawing characters.
- SFTP file browser for SSH sessions — browse, upload, download, rename, delete.
- SSH key authentication with optional passphrase; jump host / bastion support.
- Connection groups and pinning for organizing large inventories.
- Auto-reconnect on disconnect (configurable retry count).
- Quick Connect for one-off sessions not saved to the permanent list (
Ctrl+Shift+O). - Org-managed connections (read-only, lock badge) pushed from an admin sync endpoint.
- Export / import connections as JSON.
- All credentials encrypted at rest with DPAPI via Electron
safeStorage(machine-bound, platform keychain on macOS and Linux). contextIsolation: true,nodeIntegration: false,sandbox: trueon every window.- Input sanitized before storage; passwords never sent to the renderer process.
- Entra ID / Azure AD sign-in — MSAL v5 PKCE OAuth2 flow (Settings → Account).
- Org config sync — pull a managed connection list from any HTTPS endpoint (Settings → Organization).
- Group Policy — enforce settings via Windows registry keys or a Linux JSON file.
- Policy banner and locked fields in the UI when settings are managed by your organization.
| Platform | Installer formats | Architecture |
|---|---|---|
| Windows 10 / 11 | MSI, portable EXE | x64 |
| Linux (Ubuntu 20.04+, Debian, Fedora, etc.) | AppImage, .deb | x64, arm64 |
| macOS 12+ (Monterey) | DMG, ZIP | x64 (Intel), arm64 (Apple Silicon) |
- cloudflared — required for any Cloudflare Access tunnelled connection. Must be on
PATHor set a custom path in Settings.
- RDP —
mstsc.exeis included in every Windows installation. No extra steps needed. - SSH — the built-in OpenSSH client shipped with Windows 10/11. Enable it under Settings → Optional Features if missing.
- RDP — FreeRDP:
sudo apt install freerdp2-x11(orfreerdp3-x11on newer systems). - SSH/Telnet — embedded via ssh2 / net.Socket (no external client needed).
- RDP — Microsoft Remote Desktop from the Mac App Store (free). TunnelDesk generates and opens a
.rdpfile automatically. - SSH —
Terminal.appis launched viassh://URL. No extra installation needed.
- Go to the Releases page.
- Download the installer for your platform.
- Run the installer.
- On first launch, install
cloudflaredand optionally set its path in Settings if it isn't onPATH.
| Platform | File | Notes |
|---|---|---|
| Windows | TunnelDesk-x.x.x.msi |
Standard installer, no admin required (per-user) |
| Windows | TunnelDesk-x.x.x.exe |
Portable, no install needed |
| Linux x64 | TunnelDesk-x.x.x.AppImage |
chmod +x then run |
| Linux x64 | tunneldesk_x.x.x_amd64.deb |
sudo dpkg -i |
| macOS Intel | TunnelDesk-x.x.x.dmg |
Drag to Applications |
| macOS Apple Silicon | TunnelDesk-x.x.x-arm64.dmg |
Drag to Applications |
macOS note: Because the build is unsigned for community releases, you may need to right-click → Open the first time to bypass Gatekeeper.
TunnelDesk uses MSAL v5 with a PKCE public-client flow. No client secret is required.
App registration steps:
- In the Azure portal, go to Azure Active Directory → App registrations → New registration.
- Name: anything descriptive (e.g.
TunnelDesk). - Supported account types: choose the appropriate tenant scope for your org.
- Redirect URI: select Public client / native (mobile & desktop) and enter
http://localhost. - Under Authentication, enable Allow public client flows.
- Under API permissions, ensure
openid,profile,email, andoffline_accessare present. - Copy the Application (client) ID and Directory (tenant) ID.
Enter these values in TunnelDesk under Settings → Account.
Windows — registry path:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\TunnelDesk
Linux — file path:
/etc/tunneldesk/policy.json
Supported keys:
| Key | Windows type | Description |
|---|---|---|
ConfigSyncUrl |
REG_SZ |
HTTPS URL for org config sync endpoint |
SyncInterval |
REG_DWORD |
Sync poll interval in seconds (min 60) |
TenantId |
REG_SZ |
Entra ID tenant ID (locks the field in Settings) |
ClientId |
REG_SZ |
Entra ID client ID (locks the field in Settings) |
EnforceSSO |
REG_DWORD |
1 = require sign-in |
DisableManualConnections |
REG_DWORD |
1 = prevent adding personal connections |
BannerMessage |
REG_SZ |
Text shown in the policy banner at the top of the app |
AllowedProtocols |
REG_SZ |
Comma-separated list of allowed protocol identifiers |
Policy values lock the corresponding UI fields and show a lock indicator.
When ConfigSyncUrl is configured (via policy or Settings → Organization), TunnelDesk polls a JSON document and merges org-managed connections into the sidebar. These connections display a lock badge and cannot be edited or deleted.
Policy JSON format:
{
"version": 1,
"syncInterval": 300,
"managedConnections": [
{
"id": "prod-jump",
"friendlyName": "Production Jump Host",
"hostname": "ssh.prod.example.com",
"port": 22,
"username": "svc-deploy",
"protocol": "ssh-cf",
"group": "Production"
}
],
"policies": {
"disableManualConnections": false,
"bannerMessage": "Welcome to Acme Corp. All sessions are monitored.",
"allowedProtocols": ["ssh-cf", "ssh", "rdp-cf", "rdp"]
}
}The endpoint must return Content-Type: application/json and be accessible over HTTPS. Publish to Azure Blob Storage, SharePoint CDN, or any static HTTPS host.
- Node.js 20 or later
npm10 or latercloudflaredonPATHfor runtime testing (not required to build)
git clone https://github.com/5djr/TunnelDesk.git
cd TunnelDesk
npm installDevelopment (live Electron window):
npm run devBuilds the renderer with Vite and launches Electron. Reload the renderer with Ctrl+R; restart the main process manually after main-process changes.
Build renderer only:
npm run build:renderer
# then npm start to launch against the built rendererPackage installers:
# Windows — MSI + portable EXE → dist-app/
npm run dist
# Linux — AppImage + .deb → dist-app/
npm run dist:linux
# macOS — DMG + ZIP (x64 + arm64) → dist-app/
npm run dist:macCross-platform packaging (e.g. building macOS DMG from Windows) is not supported. Use the matching platform or the GitHub Actions CI workflow.
.github/workflows/release.yml triggers on any tag matching v*. It builds all three platforms in parallel on GitHub-hosted runners and uploads the artifacts to a GitHub Release automatically.
| Package | License |
|---|---|
| Electron | MIT |
| Vite | MIT |
| TypeScript | Apache 2.0 |
| xterm.js | MIT |
| ssh2 | MIT |
| @azure/msal-node | MIT |
| electron-builder | MIT |
TunnelDesk launches cloudflared as an external process. cloudflared is developed by Cloudflare, Inc. and is subject to its own license. TunnelDesk does not bundle or redistribute cloudflared.
Bug reports and pull requests are welcome. See CONTRIBUTING.md for guidelines on setting up the dev environment, code style, and the PR process.
To report a vulnerability, do not open a public issue — email hello@tym.wtf instead. See SECURITY.md for the full policy.
Copyright (c) 2026 5djr. Released under the MIT License.