User guide¶
Using a deployment your administrator set up: trust, sign-in, and each kind of resource through its native client. To build a deployment, see the Quickstart.
Examples use placeholder hosts: authority-1, proxy-1, connector-1,
alice@example.test. lab-read is an allowed database; lab-denied is visible
and denied.
Prerequisites¶
The administrator supplies:
- the client: on Linux an x86_64 static musl binary; on Windows the x86_64
.msi, which installsgdsgate.exeinto%ProgramFiles%\gdsgateand adds it toPATH; - the Proxy address and the transport CA fingerprint;
- the identity-provider instructions. You choose the local configuration path.
Examples use a POSIX shell. In PowerShell, set the same values as
$env:PROXY_ADDR, $env:PROXY_FINGERPRINT, $env:CLIENT_CONFIG, and run each
relay (db proxy, kube proxy, tcp proxy, mcp proxy) in its own window;
stop it with Ctrl+C.
: "${PROXY_ADDR:?set the administrator-supplied Proxy address}"
: "${PROXY_FINGERPRINT:?set the published transport CA fingerprint}"
CLIENT_CONFIG="${CLIENT_CONFIG:-$HOME/.gdsgate/config.toml}"
SSH_FRAGMENT="${SSH_FRAGMENT:-./gdsgate-ssh-fragment.conf}"
SSH_CONFIG="${SSH_CONFIG:-$SSH_FRAGMENT}"
SSH_CONFIG defaults to the generated fragment, used with ssh -F. If your SSH
configuration includes the fragment, set SSH_CONFIG to that file.
Do not pass a token as a command argument or commit a generated file.
0. Connect to the cluster¶
gdsgate connect writes the client settings and the transport trust anchor. It
does not sign you in. Verify the fingerprint out of band first.
An existing output file is kept unless --force is given. connect selects the
file it writes. Later access and administrative commands use that selection.
Use contexts use PATH to choose another cluster, or --config PATH for one
invocation. For several clusters, use a separate directory for each configuration
and its CA, as in keeping several clusters.
If the resident is running, contexts use PATH reloads it without stopping the
process. Run login for the selected cluster; use up when no resident is
running. Use gdsgate reload after editing the loaded client configuration. Configuration selection explains
which commands query the selection and which report the running resident.
Check the saved configuration:
| Symptom | Cause | What to do |
|---|---|---|
| First contact refused in a non-interactive shell | --fingerprint missing |
Pass the published fingerprint. |
| Fingerprint mismatch | The Proxy offers a different CA | Stop. Remove the output file and ask the administrator for the correct value. |
| Proxy unreachable | Route or address | Fix it and run connect again with the same fingerprint. |
--insecure turns off encryption and peer verification. Use it only for a
development process on the same host.
Keep the trust anchor until the administrator rotates the CA and supplies a new fingerprint.
1. Sign in¶
The default device flow prints a URL and a one-time code; approve it with the
identity provider. login --browser uses the Authorization Code flow with PKCE
on a loopback address. Provider registration, polling compatibility, claims and
error checks are in the OIDC guide. Check:
Login can succeed with an empty ls and denied connections: the token has no
group the policy permits. Ask the policy owner to check view and connect.
A job or service uses workload identity, not a person's token.
2. List what you can reach¶
One row per resource you have view on: kind, environment, labels, address. A
resource with connect and no view is connectable and not listed. Filter by
kind:
In these examples, both lab-read and lab-denied are listed. A resource name that is
not in the catalog is refused as unknown, before policy.
| Need | Use |
|---|---|
| One task or a script | The explicit command for the resource kind, below |
| Native clients used repeatedly by one user | Resident access levels, basic or direct |
| An application that cannot use a loopback address | Resident transparent, with the host owner's approval and an address pool that does not overlap local networks |
| A shared host, server, container or service | An explicit command or a workload identity; no personal Resident client |
3. SSH¶
The Resident client maintains a generated SSH configuration
for the current catalog. Include it once to use ssh RESOURCE_NAME; see
SSH audit and recordings for the
session notice shown when connecting through a resource name or local address.
To generate an SSH configuration fragment manually:
The fragment sets a ProxyCommand, the client configuration and the gdsgate
host keys. To use it from an existing SSH configuration, include it before the
matching host entries and set SSH_CONFIG to that file. Include it once.
The audit records a connect decision, and a session close when it ends.
| Symptom | Cause | What to do |
|---|---|---|
Denied on SshHost::"RESOURCE_NAME" |
Policy | Run the step-up or gdsgate requests create RESOURCE_NAME --reason 'ticket-1234' the message names, then retry; otherwise ask the policy owner. No downstream connection is made. |
| Host key changed | The host key differs from the generated fragment | Check with the resource owner. Do not relax host-key checking. |
Interactive shell¶
A normal ssh login gives a PTY; resize and interrupt work. exit closes the
session and writes the close event. On a Windows connector the default shell is
cmd.exe (%ComSpec%).
Running a command¶
The command's exit status is returned and the session is recorded.
-L: local port forward¶
Requires sshForwardLocal in policy and the destination in the backend's
allow_local_forward list.
A denied forward is refused before any bytes reach the Connector, and audited.
Ending ssh closes the listener.
-R: remote port forward¶
Requires sshForwardRemote in policy and the bind address in the backend's
allow_remote_forward list. Bind to loopback to keep the listener off the
host's network:
A denied bind is refused and audited.
-A: agent forwarding¶
Requires allow_agent_forward = true on the backend and sshForwardAgent in
policy. Both are off by default; connect and sshForwardLocal do not imply
them.
When allowed, programs in the session see SSH_AUTH_SOCK and can sign with your
keys while the session is open: the shell, what it starts, and root on the
Connector host. When refused, SSH_AUTH_SOCK is not set.
SFTP¶
A connect denial comes from gdsgate; a permission error on a file comes from
the host. On a Windows connector, paths look like /C:/..., / is the root of
the home drive, and mode changes are refused.
4. Databases (PostgreSQL / MySQL)¶
Kinds: postgres, mysql, and a cockroach backend listed as postgres.
With a running Resident client, load its database environment variables
to point psql or mysql at the published listener.
To start a loopback relay manually and point the client at it:
gdsgate db proxy lab-read --listen 127.0.0.1:5433 &
DB_PID=$!
trap 'kill "$DB_PID" 2>/dev/null || true' EXIT
psql -h 127.0.0.1 -p 5433 -c 'select count(*) from lab_table;'
In the lab the result is 3. connect is decided when the relay opens; a
backend in restricted mode also decides each statement (dbQuery). Both are
audited.
A denied resource:
This fails with a denial naming Database::"lab-denied"; no backend connection
is made. Ask for connect or dbQuery, or run the step-up the message names.
See database policy.
5. Kubernetes¶
The Resident client maintains Kubernetes contexts
under ~/.gdsgate/kube/. Load its environment to use
kubectl --context KUBE_RESOURCE, or select a generated file with --kubeconfig.
To write a kubeconfig and start the local proxy manually:
KUBECONFIG="${KUBECONFIG:-./gdsgate-kubeconfig.yaml}"
gdsgate kube login KUBE_RESOURCE > "$KUBECONFIG"
gdsgate kube proxy KUBE_RESOURCE --listen 127.0.0.1:6443 &
KUBE_PID=$!
trap 'kill "$KUBE_PID" 2>/dev/null || true' EXIT
kubectl --kubeconfig "$KUBECONFIG" get --raw=/version
The exec plugin gets a short-lived credential. Every API request is decided as
kubeRequest by verb, resource kind, namespace, name and subresource. A denied
request returns 403 before it reaches the cluster.
port-forward is refused unless the backend sets allow_port_forward; when
allowed, its bytes are audited as one channel. Delete the kubeconfig when you
are done.
6. TCP, Redis, web¶
A tcp resource is relayed as bytes; gdsgate does not read the protocol.
With a running Resident client, use its resource host and port variables
to connect redis-cli or another native client to the published listener.
To start a TCP relay manually:
gdsgate tcp proxy RESOURCE_NAME --listen 127.0.0.1:6390 &
TCP_PID=$!
trap 'kill "$TCP_PID" 2>/dev/null || true' EXIT
redis-cli -p 6390 ping
The audit records the connect and byte counts. A connect denial happens
before the backend is dialled.
Web resources are covered under Web applications.
7. MCP servers¶
gdsgate mcp proxy MCP_RESOURCE --listen 127.0.0.1:8765 &
MCP_PID=$!
trap 'kill "$MCP_PID" 2>/dev/null || true' EXIT
gdsgate mcp bridge 127.0.0.1:8765
tools/list shows only the tools you may see. Each tools/call,
resources/read and prompts/get is decided and audited as mcpCallTool,
mcpReadResource or mcpGetPrompt; a denial is a JSON-RPC error and the server
is not called. The backend's allowed_tools list always applies; Cedar per-tool
decisions apply when the backend sets enforce_tool_policy.
8. Model services¶
For an llm resource, the Connector reads the model name from each request
and decides llmCall per call. The audit row carries the model and token
counts. A model the policy does not allow, or a revoked delegation, is refused
at the Connector. When the backend substitutes the provider credential, the
client never receives it. See AI agents and
model policy.
9. Web applications¶
With a running Resident client, open the local address in its
status connection command.
Applications that require their original domain use
name interception.
To start a web relay manually:
The proxy prints a loopback address. Each request is decided as httpRequest
and audited. A 403 from the gateway is a route denial; any other 403 comes
from the application.
Reaching the outside through a web-egress resource¶
A web-egress resource is a forward proxy for outside destinations. Only
public internet addresses are dialled: private, loopback, link-local, metadata
and other special-purpose ranges are refused. Ranges your network routes are
listed by the administrator in routed_ranges. Each request is audited.
Reaching an application from a browser with nothing installed¶
Available when the deployment exposes a browser entry. The administrator gives
you its address. Decisions and audit are the same as with web proxy. When the
browser session expires, sign in with the identity provider again.
Reaching an application by its own name¶
The Resident client intercepts a resource's native_name when the name is also
listed in [client].intercept_names. Other names resolve normally. Stop the
Resident client to stop interception. See
Resident client.
10. Windows desktops¶
The listener prints a username and password for your RDP client. They are not a
Windows account, are valid until the command exits, and admit one session at a
time. --exec starts an RDP client with them: mstsc on Windows, xfreerdp on
Linux.
The backend sets the Windows account. If it offers several, choose one with
--windows-user; the policy decides. When the connector logs in to Windows
itself, you never receive the Windows password.
The session appears in gdsgate sessions list; its open and close are audited.
An account the policy does not allow is refused before Windows is contacted.
Closing the RDP client ends the command.
11. Just-in-time access¶
Used when a denial offers approval. Approving is the Cedar action
approveRequest; creating a request is not a Cedar action.
gdsgate requests create RESOURCE_NAME \
--action connect --reason 'ticket or task identifier' --ttl 900
gdsgate requests list
The request is queued with an ID. An approver runs gdsgate requests approve REQUEST_ID;
then retry. A request that was denied or has expired cannot be reused: file a
new one. See policy JIT patterns.
For a running Resident client, see access refusals
for its status values and how it picks up a new grant.
12. Multi-factor (MFA) and step-up¶
MFA at login is the identity provider's. gdsgate mfa grants create gives a one-time grant
for one action on one resource:
The default factor is a passkey in the browser. --code is for a TOTP factor
enrolled on the deployment. The next matching request is allowed once; a second
one needs a new step-up. Both are audited.
13. Managing your sessions¶
sessions list shows the sessions policy lets you see. sessions kill ends one
if killSession allows it; the kill is audited.
14. Delegating access to an agent¶
Gives a program part of your access while it runs. See AI agents.
gdsgate delegations create \
--can mcp:search@tools-dev \
--can llm:call@models-dev \
--ttl 900 --sandbox strict --model gateway \
--agent-profile PROFILE_NAME \
--exec ./agent-wrapper -- --single-search-and-single-model-call
gdsgate delegations create --list-agent-profiles lists the shipped profiles with their
source and review date. The program gets the listed capabilities while it runs;
the grant is revoked when it exits. The audit shows delegation.create,
sandbox.claim, and each tool and model call. A tool or model not in --can
is refused. A --bind-key grant stays until you revoke it; then delete its
directory.
On Windows, --sandbox basic and strict need the gdsgate-client-net
service (installed by the .msi); without it, a grant that names a resource is
refused.
What the audit log captures¶
The audit chain records authentication, policy decisions, sessions, delegation and administrative events. A row names the principal, resource kind, action, outcome, and the session or request ID where there is one. A denial row does not mean the backend was contacted.
Operators verify the chain from a workstation whose configuration opens the audit store and names the anchor key:
It prints a chain and anchor verification summary. See Operations for events and export.
Troubleshooting¶
Check in this order: version, trust, identity, catalog, policy, local relay, backend. Send the administrator the error message and its request ID.
| Symptom | Collect | What to do |
|---|---|---|
| First contact refused | Published and offered fingerprints | Ask the administrator to reconcile them. |
Login succeeds, ls is empty |
Subject, groups, Proxy address | Ask for view on the resource. |
connect denied |
Resource kind, action, request ID | Run the step-up or request-access the message names, or ask for a policy review. |
| Relay opens, native client fails | Relay output, client error | Check the local port, the generated config, and host-key or TLS trust. |
| Kubernetes context not found | KUBECONFIG, generated context file |
Load the Resident contexts in this shell, or select the file with --kubeconfig. |
Kubernetes 403 |
Verb, kind, namespace, name, subresource, reported user | Check kubeRequest policy and the cluster's RBAC permissions for the impersonated identity. |
| MCP tool missing | tools/list output, tool name |
Check allowed_tools, enforce_tool_policy, viewTools. |
| Agent loses access after exit | Delegation ID | Expected with --exec. Revoke a remaining --bind-key grant. |
Windows: start the gdsgate-client-net service from an elevated prompt |
The service is stopped | Run sc start gdsgate-client-net in an elevated prompt. |