Protocol commands¶
Common global behavior is documented in the CLI hub. The complete protocol command family follows; resource kinds are source-derived.
ssh postgres mysql kubernetes tcp mcp llm web web-egress
gdsgate ssh <target> [--exec [-- <ssh args>...]]¶
Requests an SSH access certificate for the resource named in <target>
(parsed as user@resource or resource). The cert is issued by Authority
on Allow and cached. Useful when you want to authorise up front
before the native ssh invocation.
With --exec the command, once the cert is in place, replaces itself with
ssh <target> and connects in one step: the SSH ProxyCommand wiring is passed
inline, so the ~/.ssh/config fragment from
ssh-config is not required.
Any arguments after -- are forwarded verbatim to ssh, e.g.:
| Argument | Default | Purpose |
|---|---|---|
<target> |
none | user@resource or just resource. |
--exec |
off | After minting the cert, exec ssh <target> instead of returning. |
-- <ssh args>... |
none | Trailing args forwarded to ssh. Requires --exec. |
gdsgate ssh-config [<host_pattern>]¶
Prints an OpenSSH client-config fragment to stdout that routes native
ssh through gdsgate. The --config path of this gdsgate invocation
is threaded into the generated ProxyCommand, so the native ssh reaches the
same cluster you signed into.
gdsgate --config ~/.gdsgate/client.toml ssh-config '*.gds' > ~/.gdsgate/ssh_config
# then, before the first Host block of ~/.ssh/config:
# Include ~/.gdsgate/ssh_config
A file of its own instead of an append: regenerating then rewrites it, where
>> would leave the previous fragment in place and let the older of two
matching blocks keep deciding. The include belongs before the first Host
block, because OpenSSH keeps the first value it finds for each option.
gdsgate up writes and includes this same file itself.
| Argument | Default | Purpose |
|---|---|---|
<host_pattern> |
*.gds |
OpenSSH Host pattern the fragment matches. Aliases under the pattern become the gdsgate resource id. |
gdsgate proxy-ssh <resource>¶
The SSH ProxyCommand transport: relays this process's stdio to the resource's
session over the cluster. Invoked by native ssh through ProxyCommand, and
not directly. stdout is the SSH byte stream; logs go to stderr.
gdsgate db ls¶
Lists database resources you can view.
gdsgate db login <resource>¶
Authorise a database resource: mints and caches a short-lived access certificate for it.
gdsgate db proxy <resource> [--listen <addr>]¶
Runs a localhost relay for psql / mysql. Each connection to the
listener is authorised independently (connect over the Database) and
forwarded over the cluster to the database.
| Flag | Default | Purpose |
|---|---|---|
--listen <addr> |
127.0.0.1:0 |
Local host:port to bind. :0 picks an ephemeral port (logged). |
gdsgate kube ls¶
Lists Kubernetes cluster resources you can view.
gdsgate kube login <cluster> [--server <url>]¶
Prints a kubeconfig fragment that wires kubectl to gdsgate
through an exec credential plugin. Merge it into ~/.kube/config.
| Flag | Default | Purpose |
|---|---|---|
--server <url> |
https://127.0.0.1:6443 |
The API server URL kubectl should target: the gdsgate Kubernetes listener, with kube proxy running on this same address. |
The fragment carries this invocation's --config so the exec plugin
(kube credentials) runs against the same cluster.
gdsgate kube credentials <cluster>¶
The exec credential plugin for kubectl. Prints an ExecCredential
JSON on stdout. kubectl invokes it through the kubeconfig fragment
above; do not run it by hand.
gdsgate kube proxy <cluster> [--listen <addr>]¶
Runs a localhost relay for kubectl. Each connection is authorised
(connect over the KubernetesCluster) and forwarded to the connector, which
reverse-proxies the real API with identity impersonation, and every request it
forwards is decided again, on its own, by kubeRequest.
| Flag | Default | Purpose |
|---|---|---|
--listen <addr> |
127.0.0.1:0 |
Local host:port to bind. |
gdsgate tcp ls¶
Lists raw-TCP resources you can view (Redis, internal HTTP, …).
gdsgate tcp proxy <resource> [--listen <addr>]¶
Localhost relay for any TCP client.
| Flag | Default | Purpose |
|---|---|---|
--listen <addr> |
127.0.0.1:0 |
Local host:port to bind. |
gdsgate mcp ls¶
Lists MCP-server resources you can view.
gdsgate mcp proxy <resource> [--listen <addr>]¶
Localhost MCP endpoint. The connector gates each tools/call,
resources/read and prompts/get against the policy before it reaches
the backend, and filters tools/list to the tools the policy lets you
view (viewTools); every call is audited.
The endpoint answers both shapes an MCP client comes in:
- Streamable HTTP, protocol revision
2026-07-28. Give the client the URL and nothing else. - stdio, for a client that starts a program rather than dialling a URL, where
the program is
gdsgate mcp bridge.
gdsgate mcp proxy tools-mcp --listen 127.0.0.1:8765 &
# MCP client over Streamable HTTP: http://127.0.0.1:8765/
# MCP client over stdio: command `gdsgate mcp bridge 127.0.0.1:8765`
The endpoint refuses any request carrying an Origin header, and any
whose Host is not its own loopback address, the two halves of the DNS
rebinding attack that reaches local ports from a web page. GET and
DELETE are answered 405: revision 2026-07-28 removed the standalone
event stream and protocol-level sessions, so an Mcp-Session-Id a client
sends is ignored and never echoed.
| Flag | Default | Purpose |
|---|---|---|
--listen <addr> |
127.0.0.1:0 |
Local host:port to bind. |
gdsgate mcp bridge <endpoint>¶
Speaks an endpoint's stdio framing over this process's own stdin and
stdout, for an MCP client that can only start a program. <endpoint> is
the host:port gdsgate mcp proxy printed.
// in the client's MCP server configuration
{
"command": "gdsgate",
"args": ["mcp", "bridge", "127.0.0.1:8765"]
}
A byte pipe and nothing else: it parses nothing and decides nothing, and every request through it is authorized at the connector exactly as it would be without it. Replacing it, patching it or skipping it changes no decision, which is why nothing is checked in it.
gdsgate web proxy <resource> [--listen <addr>]¶
Localhost relay onto an HTTP(S) resource: a kind = "web" application, or the
one kind = "web-egress" way out named on your grant. There is no web ls:
gdsgate ls shows web resources beside every other kind.
For an application the connector terminates HTTP and reverse-proxies each
request under the application's own name, so its Host, cookies, redirects and
links are its own rather than the address printed above. For a way out the
listener speaks the shape HTTP defines for a forward proxy, an absolute target in
the request line or CONNECT, so it is pointed at with a client's proxy setting
(curl -x http://127.0.0.1:<port> https://github.com), not opened in a
browser; gdsgate delegate --exec does this automatically for a program, see
Endpoints: what the program is given above.
| Flag | Default | Purpose |
|---|---|---|
--listen <addr> |
127.0.0.1:0 |
Local host:port to bind. |
See Configuration → The web lane and Policy → HTTP(S) application routes.
gdsgate web trust [--quiet]¶
Prints the certificate root the resident client signs an application's own
domain with, when [client].intercept_names and
a catalogued native_name agree on one. See
Resident client → An application's own name.
The certificate goes to stdout; an explanation of what installing it means goes
to stderr, so gdsgate web trust --quiet > gdsgate-local-root.crt
produces a plain file and an interactive run still prints the paragraph.
Makes a root for this machine if there is none, since running the command is
already the decision to install one, and installs nothing: it prints the commands
for the system trust store, NSS and Firefox, and how to undo each of them. What is installed is the certificate this command prints and
nothing else; the file under ~/.gdsgate holds the private key too, and a
trust store's own directory is world-readable.
| Flag | Default | Purpose |
|---|---|---|
--quiet |
off | Print only the certificate, with no explanation on stderr. |
ls login proxy
ls login credentials proxy
ls proxy
ls proxy bridge
proxy trust