Skip to content

feat(db): add experimental db tunnel (MySQL over WebSocket) - #249

Open
mcolakovic-godaddy wants to merge 1 commit into
godaddy:mainfrom
mcolakovic-godaddy:feat/db-tunnel
Open

feat(db): add experimental db tunnel (MySQL over WebSocket)#249
mcolakovic-godaddy wants to merge 1 commit into
godaddy:mainfrom
mcolakovic-godaddy:feat/db-tunnel

Conversation

@mcolakovic-godaddy

Copy link
Copy Markdown

Summary

Adds gddy db tunnel, an experimental streaming command that opens a local TCP port and bridges raw MySQL bytes over a single WebSocket per connection to an application's agent, which in turn dials the application's own database. This lets a developer point any local MySQL client (mysql, TablePlus, DataGrip, an ORM) at a hosted app's database without exposing that database publicly.

Full design and rationale: docs/proposals/db-tunnel.md.

How it works

  • Byte pump, not a proxy. The tunnel never parses the MySQL protocol and never injects credentials. MySQL authentication and TLS are negotiated end-to-end between the local client and the database, so the CLI and the agent see only opaque bytes.
  • One WebSocket per TCP connection. Each accepted local connection opens its own WebSocket; frames are binary and carry raw protocol bytes in both directions.
  • Token mint. The command authenticates the one-time token mint with the CLI's own OAuth credential, then receives a short-lived, app-scoped token and the agent URL from the hosting API and presents that token to the agent. No long-lived secrets are stored.
  • Stage-gated. The db group is registered behind the experimental stage and hidden at the GA default, so it does not appear in normal help output.

Security

  • No credential injection or interception — DB auth and TLS are end-to-end between client and database.
  • A short-lived, app-scoped mint token is obtained per invocation via the existing OAuth credential, presented to the agent, and never persisted.
  • The local listener binds to loopback.

Testing

  • cargo fmt --check, cargo clippy -- -D warnings, cargo test (757 tests), cargo check --locked, and the module-size check all pass.
  • Unit tests cover WebSocket URL construction (ws/wss, with and without an explicit port) and the token-mint request/response contract.

Notes

  • This is the client half of the feature. The server-side token mint and the agent's WebSocket handler are delivered separately and are not required for this change to build or ship — the command is inert until those are available and the experimental stage is enabled.

Add `gddy db tunnel`, an experimental streaming command that opens a local
TCP port and bridges raw MySQL bytes over a single WebSocket per connection
to an application's agent, which dials the app's own database. The tunnel is
a byte pump: it never parses MySQL and never injects credentials, so MySQL
auth and TLS are negotiated end-to-end between the client and the database.

The command authenticates the one-time token mint with the CLI's own OAuth
credential, receives a short-lived app-scoped token and the agent URL from
the hosting API, and presents that token to the agent. The `db` module is
gated behind the experimental stage and hidden at the GA default.

Includes the public proposal at docs/proposals/db-tunnel.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 4, 2026 16:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The WebSocket URL builder can generate invalid URLs for IPv6 agent hosts (missing required brackets), which can break connections in valid environments.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds an experimental gddy db tunnel command group for tunneling MySQL traffic from a local TCP listener to a hosted app’s agent via per-connection WebSockets, plus the hosting API client support needed to mint short-lived agent tokens.

Changes:

  • Registers a new experimental db command group and adds CLI-stage gating tests.
  • Implements db tunnel as a streaming command that relays raw bytes between TCP and WebSocket connections.
  • Extends the hosting Node.js client with an agent-token mint endpoint and associated unit test; adds required Rust dependencies and a design proposal doc.
File summaries
File Description
rust/src/main.rs Wires in the db module and adds a gating/help-surface test for db tunnel.
rust/src/hosting/nodejs/client.rs Adds get_agent_token API call and a unit test for request/response shape.
rust/src/db/tunnel.rs Implements the streaming tunnel command, URL derivation, token minting, and byte relay.
rust/src/db/mod.rs Adds the experimental db group wiring and registers db tunnel.
rust/Cargo.toml Adds futures-util and tokio-tungstenite dependencies for WS + stream utilities.
rust/Cargo.lock Locks new transitive dependencies for tungstenite/rustls stack.
docs/proposals/db-tunnel.md Documents the design, security model, and rationale for db tunnel.
Review details
  • Files reviewed: 6/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread rust/src/db/tunnel.rs
Comment on lines +482 to +488
let host = parsed
.host_str()
.ok_or_else(|| GddyError::network(format!("agent URL '{agent_url}' has no host")))?;
let authority = match parsed.port() {
Some(port) => format!("{host}:{port}"),
None => host.to_owned(),
};

@jpage-godaddy jpage-godaddy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great.

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.

3 participants