Skip to content

Client configuration

Paths in the tables are relative to [client] or its nested heading. Check parsing and address rules with gdsgate doctor --config <PATH> --json. See the client connection guide.

[client]

Used by: Client, and, for the addressing keys, the Proxy.

Trust anchor for the client commands (login, ssh, db, kube, tcp, mcp, ca) and settings of the resident client (gdsgate up).

gdsgate connect writes this section: it fetches the cluster settings and writes ~/.gdsgate/config.toml and the trust anchor beside it. Commands read that file when --config is not given.

Addressing keys are also read on the Proxy

The Proxy publishes transport_sni, [client.direct].v4_pool, [client.direct].basic_port_range and [client.transparent].dns_zone / v4_pool to clients that run gdsgate connect. Set them in the Proxy configuration to give all clients the same values.

access, resolver, local_user_only and privileged_port_offset are not published; set them on each host. The published bundle holds no identity; clients sign in with gdsgate login or gdsgate identity bootstrap.

Key Type Default Purpose
transport_ca string unset Path to the cluster transport CA (PEM) that verifies the Proxy's TLS: the transport-ca.pem a registered Proxy or Connector writes into its state_dir. Unset: the host's trusted CAs are used; a certificate they do not accept is refused. For plaintext see allow_insecure_http.
transport_sni string unset TLS server name the client sends and verifies. Unset: gdsgate.internal with transport_ca, or the dialed host name with the host's trusted CAs. Set it (for example proxy.gdsgate.internal) when a front routes several roles on one address by server name.
allow_insecure_http bool false Allow plaintext http:// to the gateway. The identity token and all session traffic are then unencrypted. For a local development gateway without TLS.
access enum auto Where the resident client exposes resources. off: no local listeners; use the per-command relays. basic: one port per resource on 127.0.0.1. direct: one loopback address per resource, with low protocol ports shifted by privileged_port_offset. transparent: one virtual address per resource on an interface the client creates (Linux: a TUN device, needs CAP_NET_ADMIN; Windows: a Wintun adapter held by the gdsgate-client-net service). auto: the highest level this host allows. An explicit level that cannot run is an error; only auto falls back.
local_user_only bool or unset Linux: true; other platforms: false Restrict resource connections to the resident owner's OS UID. Linux needs the trusted kernel filter command and CAP_NET_ADMIN; normal up installs the system service with one elevation. A protection failure stops startup or leaves the endpoint unbound. Explicit true on other platforms refuses startup. false exposes reachable endpoints to other local accounts. Set locally; not published by the cluster. See owner protection.
resolver enum auto How resource names are served, set apart from access. off: no names. hosts: a block in the system hosts file. system: the client serves the zone and the system resolver points at it. auto: system, else hosts, else off. Linux: system needs port 53, a network link, and host lookups that go through the system resolver, so it works only with access = transparent. Windows: system sets an NRPT rule through the gdsgate-client-net service and works at any access level. A mode that cannot run falls back; gdsgate status shows why. See Resident client → Names.
warm_access bool true Fetch each resource's access certificate on the catalog pass. The first connection then needs no round-trip, and gdsgate status shows which resources are reachable. Certificates are renewed before expiry. Refused resources are not retried on every poll; resources that need a single-use step-up grant are not requested. See Resident client → Certificate prefetch.
notify bool true Show a desktop notification on refusal, in addition to the log and gdsgate status. Linux: notify-send; if it is missing, gdsgate status says so. Windows: a toast through Windows PowerShell. The same refusal is shown at most once per 15 minutes.
step_up_on_denial bool false Start the step-up a refusal offers. Without a terminal only the passkey confirmation can start; it opens a browser window. One-time codes and access requests are always reported as a command to run. See Resident client → When access is refused.
intercept_names array of strings [] Domains outside [client.transparent].dns_zone this machine answers for, such as app.example.com. A name is answered only when it is here and is the native_name of a kind = "web" resource in the catalog. Each entry is a whole name of at least two labels, outside dns_zone. See Resident client → An application's own name.
agent_key_source enum proxy Source of the keys the agent offers. proxy: requests go to the user's running agent (SSH_AUTH_SOCK); gdsgate reads no key material. key_files: the default ssh key files under ~/.ssh are loaded into the resident process. Encrypted key files are skipped and named in the log. Windows: with SSH_AUTH_SOCK unset, the OpenSSH agent pipe \\.\pipe\openssh-ssh-agent is used.
agent_signatures_per_process u32 64 Signatures one local ssh process may get for one resource within agent_signature_window. 0 is refused.
agent_signatures_per_resource u32 512 Signatures for one resource within agent_signature_window, across all channels and processes. 0 is refused.
agent_signature_window u64 seconds 600 Sliding window for both signature counts. 0 is refused.
agent_identities_max u32 5 Maximum identities listed, most preferred first. sshd allows six authentication attempts by default. 0 is refused.
agent_auth_attempts_max u32 5 Signatures served on one agent socket connection. 0 is refused.
agent_frame_max u64 bytes 32768 Largest agent frame read; a longer frame closes the connection. 0 is refused.
agent_channel_ttl u64 seconds 600 Maximum lifetime of one agent socket connection. 0 is refused.
[client]
transport_ca = "/etc/gdsgate/transport-ca.pem"
# transport_sni = "proxy.gdsgate.internal"
access = "auto"

The transport_sni name must be in the certificate the Proxy presents, or the handshake fails with a name mismatch. Reissue the Proxy's certificate first (see [connector].authority_transport), then change the clients.

[client.direct]

Settings shared by the basic and direct levels.

Key Type Default Purpose
v4_pool string 127.70.0.0/16 Address pool for direct. Must be inside 127.0.0.0/8; any other pool is refused at start-up.
basic_port_range string 15000-15999 Port range for basic, as first-last. Must be unprivileged.
privileged_port_offset u16 10000 Added to protocol ports 1–1023 at direct, including an auto fallback to direct. 22 → 10022, 80 → 10080, 443 → 10443; ports 1024–65535 are unchanged. Allowed: 0 (disable), or 1023–64512. Does not change basic, transparent or the upstream resource port. Set locally; the cluster bundle does not publish this key.
catalog_sync_secs u64 60 Catalog poll interval of the resident client. Minimum 5. The client also polls early (at least 5 seconds after the last poll) when asked for an unknown name in its zone, and on gdsgate status --refresh.
[client.direct]
v4_pool = "127.70.0.0/16"
basic_port_range = "15000-15999"
privileged_port_offset = 10000
catalog_sync_secs = 60

A resource keeps its address; ~/.gdsgate/endpoints.json records the assignments. Changing v4_pool or basic_port_range renumbers resources outside the new range, and saved connection strings for them stop working.

[client.transparent]

Settings of the transparent level. dns_zone and reuse_grace_secs apply at every level; [client].resolver decides whether names are served.

Key Type Default Purpose
v4_pool string 198.18.0.0/15 Pool of virtual addresses, routed to the interface. Must be outside 127.0.0.0/8 and must not overlap an existing route.
v6_pool string unset Accepted and ignored; only IPv4 is assigned.
dns_zone string gds One-label zone for resource names, for example pg-prod.gds.
reuse_grace_secs u64 86400 Retention of local records for removed resources, capped at one day. 0: delete at the next cleanup. Expired records leave the state file and status. Endpoints published in the current run remain reserved in memory until restart; see Resident client → when a resource goes away.

The pool's first host address (198.18.0.1 by default) is assigned to the interface; resources start at the second. See Resident client → the transparent level.

[[client.agent_resources]]

Resources this machine serves the user's SSH agent to. One entry per resource; empty by default.

The agent is served only when the resource also has onward_auth = "client_key" in the catalog (gdsgate authority resources set).

Key Type Default Purpose
resource string required Resource id as in the catalog. *, ?, ! and whitespace are refused. A duplicate entry is refused.
key string unset Key file offered first for this resource; the others follow in source order. With agent_key_source = "key_files" it is read as a private key. With proxy only its public half is read, to pick which agent identity goes first. A private key file with its .pub beside it works for both.
[client]
agent_key_source = "proxy"

[[client.agent_resources]]
resource = "github"
key = "~/.ssh/id_ed25519"

For each listed resource that has client_key and a catalog name, the resident client binds a socket under ~/.gdsgate/agents/ and writes a stanza into ~/.gdsgate/ssh_config:

Host github
    IdentityAgent  /home/you/.gdsgate/agents/6f1bd0a4c2e8117f3b95d6c04ea7b2c9.sock
    ForwardAgent   yes

The socket file name is a fingerprint of the resource id. ~/.gdsgate/agents/index.json maps fingerprints to resources. On Linux the index and the sockets are readable by the owner only (mode 0600). On Windows each socket is a named pipe with the same path, accessible to the owner only, and ssh is pointed at the pipe.

The stanza's Host is the catalog name of the resource. SSH_AUTH_SOCK is not read or changed, and other connections of the user are not affected.

Symptom Cause What to do
No stanza for a resource the catalog confirms this machine has not named it add a [[client.agent_resources]] entry for it
No stanza although the entry is there the catalog confirms no client_key for it gdsgate authority resources set <id> --onward-auth client_key
No stanza although both agree the resource has no catalog name (its id contains _ or .); gdsgate doctor names the resource gdsgate authority resources set <id> --hostname <label>
no agent is served: the keys could not be reached in the client's log agent_key_source = "proxy" and SSH_AUTH_SOCK names no socket (Linux), or nothing answers the OpenSSH agent pipe (Windows) start an agent for this user, or set agent_key_source = "key_files"
a key file is encrypted and was left out agent_key_source = "key_files" and the key has a passphrase add the key to a running agent and use proxy, or use a key file with no passphrase
the agent refused a signature: the limit is spent one of the agent_* limits was reached the limit field of the log line names the key; raise it if the workload needs more