Skip to content

feat(connections): Cloudflare Access TCP tunnel integration (#1285)#1407

Merged
datlechin merged 6 commits into
mainfrom
feat/1285-cloudflare-tcp-tunnel
May 24, 2026
Merged

feat(connections): Cloudflare Access TCP tunnel integration (#1285)#1407
datlechin merged 6 commits into
mainfrom
feat/1285-cloudflare-tcp-tunnel

Conversation

@datlechin

Copy link
Copy Markdown
Member

Closes #1285.

Connect to a database behind Cloudflare Access without running cloudflared by hand. TablePro now starts and stops cloudflared access tcp with the connection, the same way it manages SSH tunnels: it picks a free loopback port, supervises the process, waits until the local port accepts connections, points the driver at 127.0.0.1:<port>, and tears the process down on disconnect, app quit, or crash.

What's included

  • Connection form: a new "Cloudflare Tunnel" pane, peer to SSH. Fields for the Access hostname, auth method, listener port (automatic or fixed), an optional "expose to LAN" toggle, and a cloudflared binary path with auto-detect. SSH and Cloudflare are mutually exclusive (validated in the form, with a runtime guard).
  • Auth: browser sign-in (with an explicit "Sign In with Browser" button that runs cloudflared access login so the SSO happens up front) and service tokens (stored in the Keychain, passed via environment variables, never on the command line).
  • Process supervision: a CloudflaredRunner protocol with a Process-backed implementation, supervised by a CloudflareTunnelManager actor that mirrors SSHTunnelManager (App Nap hold, death-triggered backoff reconnect, synchronous teardown on quit).
  • No orphans: SIGTERM on disconnect and applicationWillTerminate, plus a launch-time sweep of PIDs recorded by a previous session that crashed. The sweep verifies the live PID is still cloudflared (proc_pidpath) before signalling, so a recycled PID is never killed.
  • Readiness: detected by polling a TCP connect to the loopback port, not by scraping cloudflared's output. stderr is scanned only for the browser sign-in prompt and startup errors.

Notes

  • Using the feature needs cloudflared installed (brew install cloudflared).
  • Service tokens require the Access application policy to use a Service Auth rule; the pane says so, since otherwise Cloudflare still prompts for a browser login.
  • The tunnel config is device-local and excluded from iCloud sync, like SSH tunnel mode.

Testing

  • Unit tests for the model Codable round-trips, the tunnel manager (fake runner covering readiness, browser-auth detection, startup failure, teardown, and the stale-PID sweep), and pane validation.
  • swiftlint lint --strict is clean.

@datlechin datlechin merged commit 0ee025c into main May 24, 2026
2 checks passed
@datlechin datlechin deleted the feat/1285-cloudflare-tcp-tunnel branch May 24, 2026 07:45
datlechin added a commit that referenced this pull request May 24, 2026
…1410)

* feat(datagrid): add native date/time picker for date columns (#1405)

* refactor(datagrid): centralize chevron-kind check and extract testable picker components (#1405)

* fix(connections): add missing TableProPluginKit import for tunnel SSL rewrite (#1407)

* refactor(datagrid): use native SwiftUI graphical DatePicker for date cells (#1405)

* fix(datagrid): use .hourAndMinute on macOS and preserve original seconds in date picker (#1405)

* feat(datagrid): custom SwiftUI calendar picker with seconds for date cells (#1405)

* refactor(datagrid): extract testable CalendarMonth and add accessibility labels to date picker (#1405)

---------

Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cloudflared access tcp tunnel integration

1 participant