Resident client¶
The Resident client is an optional local daemon. It keeps the identity and catalog current, assigns a loopback address to each visible resource, and regenerates native-client files when the catalog changes. It is a convenience layer over the explicit commands in the User guide, not a second authorization system.
Reader: a user deciding whether this machine should carry access for one shell,
several local applications, or the whole host. The deployment owner supplies a
Linux x86_64 musl binary and a client configuration. The examples use the
canonical lab resources authority-1, proxy-1, connector-1, lab-read,
lab-denied, and principal alice@example.test.
Access levels¶
access and resolver are independent settings. The first controls how an
application reaches a local relay. The second controls how names are published.
Decide whether this machine should run a Resident client before choosing a level:
| Machine | Recommended starting point | Required owner decision |
|---|---|---|
| Personal Linux workstation | basic; move to direct only for a native-client need |
user owns identity, generated files, listeners, and cleanup |
| Managed desktop | basic under the managed user |
desktop owner approves service policy, resolver changes, trust, rollback, and removal |
| Shared host | off or per-user basic |
host owner accepts that another process under the same user can reach the listener |
| Server or non-interactive service | explicit command or reviewed workload identity | service owner supplies supervision, renewal, state paths, and incident response |
| Container | explicit command by default | container owner proves persistent identity/state and accepts that transparent changes only the granted network namespace |
The supported public client target is Linux x86-64 with the administrator- supplied static musl binary. Another platform requires a separate support record; a successful local build is not that record.
| Level | What it publishes | Host and permission boundary |
|---|---|---|
off |
no local access | safest default; use explicit commands |
basic |
loopback listeners | applications on this user account can reach them |
direct |
loopback listeners and direct native paths | may bind privileged ports when the host permits it |
transparent |
a virtual interface and per-resource addresses | Linux network namespace and CAP_NET_ADMIN are required |
auto |
the strongest level the host can prove | degrades to a supported lower level and explains why |
Action on the client host:
Expected result: up waits until the selected level is settled and status
reports the level actually serving. Positive proof is a local address for a
visible resource and a successful native request. The nearest negative is a
catalogued but denied resource: its address, name, and status row remain stable,
but the gateway refuses the connection and reports the reason. Recovery is to
choose a lower level or fix the host capability; do not treat a degraded level
as transparent. Cleanup is gdsgate down, followed by checking that managed
listeners and names are gone.
Privileged ports at direct¶
direct may request a low port only when the host grants that bind. A refusal
means the kernel or service policy rejected the bind, not that Authority denied
the resource. Use a high loopback port or basic; never grant broad privilege
to make a user-facing example pass. Positive proof is the actual listener
address shown by status, not a requested port.
The transparent level¶
transparent routes traffic addressed to the client's virtual pool through the
resident process. It is intended for applications that cannot be configured
with a local proxy. It changes host routing, so treat it as system-wide for the
duration of the daemon.
Capabilities¶
The process needs Linux support for a virtual interface, a configured address
pool, and the ability to install routes. The daemon reports each missing
property in status --explain. This is not a container or kernel boundary: an
application that can change host networking can affect more than a resident
client's managed entries.
Requirements¶
Prerequisites are Linux, a non-overlapping private address pool, and the
administrator's permission to grant CAP_NET_ADMIN to the daemon path. The
pool must not overlap the host LAN or another virtual network. Test with the
safe basic level first, then request transparent:
Expected result: ACCESS and SERVING report transparent, and a test request
to a visible resource succeeds. The nearest negative is a host capability or
pool conflict; the daemon must refuse or degrade without claiming transparent
coverage. Recovery is to select basic or fix the pool and capability. Cleanup
is down plus a check that the managed interface and routes have been removed.
Tradeoffs¶
Transparent access reaches applications that ignore proxy variables, but it
also applies to every process that can route to the pool. A loopback listener is
not a complete isolation boundary either: another process under the same user
can use it. Choose basic on shared machines and use explicit client commands
for sensitive resources.
Connection identity¶
The resident daemon holds the identity for the configured user and obtains
short-lived resource access certificates. A local address does not grant a new
right: Authority still decides connect, and request-aware lanes decide their
own operations. Positive evidence is a successful request with the expected
principal in audit. A stale or revoked certificate yields ACCESS refusal and
must not be worked around by dialing the backend directly.
Shared machines¶
On a shared machine, use off or basic with a per-user configuration. Avoid
transparent, intercept_names, and a service unit unless the host owner
accepts their system-wide consequences. A Resident socket is not a credential,
but a process that can reach it may use the access of its owning user. Cleanup
must include down, generated-file removal, and identity-cache removal at
account retirement.
Names¶
Names are another independent choice. resolver = off publishes no names;
hosts manages an owner-marked block in the hosts file; system serves the
configured zone and points the system resolver at it; auto chooses the
strongest mode the host can safely configure. A resolver downgrade does not
change the access level.
Name resolution per access level¶
| Access | resolver = off |
hosts |
system |
auto |
|---|---|---|---|---|
off |
no names | managed hosts entries if allowed | explicit system resolver if configured | hosts or off |
basic |
no names | managed hosts entries | possible when the host routes queries to the daemon | system, hosts, or off |
direct |
no names | managed hosts entries | possible without transparent access | system, hosts, or off |
transparent |
no names | managed hosts entries | normally required for whole-host names | system or hosts |
The system mode is not implied by transparent, and it is not forbidden at
direct or basic. Record the chosen mode in the deployment handoff.
hosts¶
Prerequisite: permission to edit the host's managed block. Action:
Expected result: the name maps to the current assigned local address. Positive
proof is the managed marker and a request through that address. The nearest
negative is a missing or read-only hosts file; status must say names - or
names ?, not claim a working name. Recovery is resolver = system where the
host allows it, or explicit loopback addresses. Cleanup is down, which removes
only the block owned by this configuration.
system¶
system requires a daemon listener, a zone, and a host resolver path that sends
queries to it. Verify both the daemon and the system resolver:
The nearest negative is a successful local daemon with a system resolver that
still asks another server. Recovery is to restore the prior resolver settings
or switch to hosts; never leave a partial resolver redirect on uninstall.
Verifying name resolution¶
Use status --explain to see the selected resolver, managed state, and any
downgrade reason. Test one positive catalog name and one name outside the
catalog. The second must not resolve to a managed resource. Cleanup is to run
down and repeat both lookups, then inspect only the daemon-owned markers.
An application's own name¶
A web resource may declare a native_name that belongs to the upstream
application. The Resident client intercepts it only if the user also places the
whole name in [client].intercept_names. Catalog declaration alone cannot widen
the user's opt-in.
Actor: a user who owns the client and the application-name decision. Prerequisites:
the catalog has the matching web resource and the client configuration names
the exact domain. Action: start the Resident client, then open the name with the
browser or HTTP client. Expected result: the application sees its original
host name. Positive proof is the expected certificate and an httpRequest row.
The nearest negative is a name in only one of the two lists; the client must
leave it untouched. Recovery is to reconcile the catalog and local opt-in.
Cleanup is removing the opt-in and running down.
Certificate root for intercepted names¶
The owner must install the deployment's public certificate root in the browser or native client trust store before interception. The generated certificate is not a credential and does not prove policy access. A trust warning is a TLS configuration failure; do not click through it. Remove the root when retiring the deployment.
Limitations¶
Interception affects the whole host's DNS and TLS behavior for the opted-in names. It does not intercept a name absent from the catalog, and it cannot turn an HTTP application denial into a network success. Native names also depend on the resolver mode and can be unavailable during a downgrade.
Status output¶
status distinguishes identity, catalog, names, listener, access, and serving
states. ok means the check completed positively; ? means control-plane
uncertainty; - means the check was not requested. Example fields are stable
concepts, not a promise that every release prints identical spacing:
Start-up sequence¶
The daemon validates settings and the access level, refuses to start over an
existing client, signs in the parent when needed, starts the child or foreground
process, binds its socket, settles the interface and names, fetches the catalog,
assigns addresses, generates native files, and then reports serving state.
The source currently waits up to 10 seconds for the socket and 3 seconds for
name/interface settlement. These timings are version-sensitive; use status
instead of scripting exact sleeps.
Background execution¶
gdsgate --config "$CLIENT_CONFIG" up
gdsgate --config "$CLIENT_CONFIG" status
gdsgate --config "$CLIENT_CONFIG" down
up returns after the daemon is ready enough to report, not merely after a
child process exists. Expected result is a positive SERVING state. The
nearest negative is an existing client or an identity refusal; the command must
leave the old process and its state unchanged. Recover by inspecting
status --explain, then retry after the cause is fixed. Cleanup is down.
The client journal¶
The daemon journal records startup decisions, degradation, listener changes, and errors. It must not contain private keys or provider tokens. Use the host's service-log reader or the configured log path supplied by the owner. A malformed generated state file is a local recovery problem: stop the daemon, preserve the file for diagnosis, and regenerate it only after verifying the config.
--foreground¶
Use foreground mode on the command host when diagnosing startup or running a supervised service:
Expected result: the command remains attached while the daemon serves. Positive
proof is the same status state and a test request. The nearest negative is a
startup error in the terminal; fix that error before switching to a service.
Interrupting foreground mode is cleanup and must remove managed state through
the normal shutdown path.
Automatic authentication¶
When no usable identity exists, up can invoke the configured login path. A
browser choice is explicit:
Expected result is a resident process under the signed-in principal. The nearest negative is a non-interactive service with no token or browser. Use a workload identity or a pre-provisioned service route instead of putting a human token in a unit file. Cleanup is expiry and cache removal.
Certificate prefetch¶
With warm access enabled, the daemon requests access certificates during the
catalog pass. status then distinguishes a resource that is visible from one
that is ready to connect. A refusal is cached with its reason and is not polled
continuously. Positive proof is ACCESS ok; the nearest negative is
ACCESS step-up or ACCESS denied. Recover with the named one-time step-up or
policy change, then wait for the next catalog pass. Cleanup is certificate
expiry, not manual key copying.
Address stability¶
Assigned addresses remain stable for a running client and are not immediately reused after a resource leaves the catalog. The reuse grace period is a safety boundary against an old application reaching a new resource. Positive proof is the same resource ID in successive status reports. Recovery from an address conflict is a client restart after the owner resolves the pool; do not edit the state map by hand.
Resources removed from the catalog¶
When a resource disappears, the client marks it unavailable, stops serving its
address after the configured grace, and removes generated native entries on the
next safe update. Existing sessions are closed by their own revocation/session
rules. The nearest negative is a stale name still resolving locally; run
status --explain, stop the client if needed, and remove only managed entries.
Address reuse¶
An address is reused only after the grace period and a restart that confirms no never-used address remains. This prevents a stale process from silently talking to a different resource. Record the old and new resource IDs when reviewing a reuse event. Cleanup is the same managed-state removal path.
Generated files¶
Generated files are owner-only, written atomically, and marked so the daemon can replace only its own content. They are not credentials. SSH host keys remain in the native client's known-hosts store; Resident does not make a host-key change safe. A generated kubeconfig or environment file contains routing metadata and short-lived endpoints, not a license to bypass Authority.
Inspect the generated directory before handing it to another user:
Expected result: paths and resource states match the current catalog. The
nearest negative is a partial file after an interrupted update; stop the client,
restore the previous atomic file if the owner has one, and restart. Cleanup is
down followed by removal of files marked as managed by this client. Never use
rm against an unreviewed directory.
Shutdown¶
Normal cleanup is:
Expected result: no resident socket, no managed listeners, and no managed
names. down is idempotent. After a crash, the next up detects stale state,
cleans only its own markers, and reports anything it could not remove. If the
host was powered off, inspect the interface, routes, hosts block, and resolver
before re-enabling transparent mode. Uninstall cleanup also removes the client
identity cache and service authorization, after active sessions are terminated.
Safe uninstall¶
The user and host owner perform removal in this order:
- End or transfer active sessions, and retain the request or session IDs needed for the deployment's audit record.
- If a service unit owns Resident, stop and disable that exact unit. Run
gdsgate downas the same user and with the same configuration that ranup. - Require
status --explainto show no Resident socket, listener, managed address, or served name. Inspect the managed interface, routes, hosts block, and system resolver against their pre-install record. - Restore only the resolver, hosts, trust, and service entries marked as owned by this installation. Leave unrelated host configuration unchanged.
- Remove the exact generated fragments, endpoint map, socket directory, identity cache, and service-owned state paths recorded by the configuration. Review every resolved path before deletion; do not recursively remove a parent configuration or home directory.
- Run a negative native-client and name-resolution check. The old endpoint must not listen or resolve, while an unrelated host entry and resolver path must still work.
If any managed route, name, listener, or file owner cannot be reconciled, stop the uninstall and restore the last known host configuration. Do not erase the evidence needed to distinguish stale Resident state from unrelated host state.
Access refusals¶
The Resident client keeps a refused resource's local address, name, and status
row so a denial does not silently renumber other resources. The address does
not bypass the refusal: the gateway still denies the connection. A refusal can
come from identity, catalog visibility, connect policy, a per-request action,
an expired certificate, or a host capability. The message should name the
operation, cause, and safe next action.
Refusals in gdsgate status¶
ACCESS denied means policy or identity refused the resource. ACCESS step-up
means a one-time grant may cure it. ACCESS ? means the control plane could not
be reached and the cached result is not a new allow. SERVING - means no local
listener was requested. Do not interpret ? as success.
Step-up grants are single-use¶
A step-up grant belongs to one principal, resource, and action. Prefetch does not spend it, because doing so would authorize a connection the user did not make. The next matching operation consumes it once. A second operation is the nearest negative and must be denied. Recover by minting a fresh, narrow grant.
Desktop notifications¶
Notifications are a convenience for a local user, not an authorization channel. If the notification program is unavailable, the refusal remains in status and the journal. A service account must not depend on a desktop notification for recovery.
Refusals inside an SSH connection¶
An SSH session can open while a later forward or downstream action is denied.
Keep the connect decision separate from sshForwardLocal,
sshForwardRemote, and native host-key failures. Positive evidence is the
specific channel that opened; the nearest negative names the channel that did
not. Close the session after recovery or policy review.
Resolving access failures¶
Check in order: status --explain, identity freshness, catalog row, action
name, local listener, then backend reachability. Use gdsgate --no-remediate
for a non-interactive negative test. Never test a policy denial by bypassing the
Proxy.
Reading gdsgate status¶
Use the compact view for a quick handoff and JSON for automation:
The report distinguishes these states:
| Field | ok |
? |
- |
|---|---|---|---|
| identity | usable local identity | control-plane freshness unknown | not requested |
| catalog | current catalog | refresh uncertain | not requested |
| names | resolver serving | resolver state uncertain | names disabled |
| listener | local listener bound | bind status uncertain | no listener requested |
| access | policy/certificate usable | cached decision only | not warmed |
| serving | request can reach its relay | tunnel uncertain | no resource served |
Resources without an active connector¶
A catalog row can exist while no Connector serves it. status reports that
state as declared but not serving; no local address is evidence of a working
backend. Recovery is for the administrator to register connector-1 or the
appropriate Connector and publish the resource again. Cleanup is removing a
stale catalog row through the Admin guide.
Status details¶
--explain includes the resource ID, kind, action, identity state, connector
state, local address, and last refusal. Treat its output as diagnostic metadata,
not a credential. A JSON consumer should fail closed when a required field is
? or -.
Runtime files and state¶
The client configuration, identity cache, resident socket, generated endpoint
map, and generated native fragments have separate purposes. The exact paths
come from the user's configuration and service environment. Keep private keys
mode 0600, keep generated files owner-only, and back up neither as a shared
credential archive. The endpoint map is local state and may be regenerated.
Running under sudo¶
sudo gdsgate changes the user, configuration lookup, identity cache, socket,
and generated-file owner. It does not make a user policy allow. Use an explicit
--config and a deliberate output directory if a privileged port is required,
then inspect status as the same user that will run the native client. Do not
run the resident client as root on behalf of an unprivileged user unless the
service design explicitly accepts that shared boundary. Cleanup both identities
and their managed files.
As a service¶
The service path is for a host owner who wants access to survive a login shell. Prerequisites are a dedicated service account, an explicit configuration, local authorization for the service action, and a workload identity or other non-interactive login path. The service must not store a human browser token in an environment file.
The system unit¶
Install the supplied unit through the host's service manager, review its user,
configuration, capabilities, and generated-file directories, then start it.
Expected result: the unit is active and gdsgate status --json reports the
intended access. The nearest negative is a unit that is active but has no
identity, catalog, or serving state. Recovery is to fix that state, not to add
unbounded privileges. Cleanup is stop, disable, down, and removal of the
service-owned identity and generated files.
Names under the system unit¶
Names are owned by the service account and its resolver configuration. A unit
that edits a host-wide resolver or hosts file must document that ownership and
its rollback command. Positive proof is a name lookup as a normal user. The
nearest negative is a name that works only as the service account; fix routing
or use a per-user hosts mode. Cleanup restores the pre-service resolver.
/etc/hosts under a service¶
The unit may manage a marked block only when the host owner grants that scope. On stop or uninstall, remove that block and leave unrelated entries unchanged. Verify with a positive lookup before start and a negative lookup after stop.
Completion¶
Generate shell completion without contacting Authority:
Resource completion reads local Resident state and may be empty when the daemon is stopped. It is not evidence that a resource is reachable. Cleanup is removal of the generated completion file when the binary is retired.
Settings¶
The complete configuration reference is Configuration.
For this page, record at least access, resolver, warm_access,
step_up_on_denial, the transparent address pool, intercept_names, generated
file roots, and the service user. Mark any version-sensitive host capability
and the date it was last checked. The next safe action after a setting change
is gdsgate doctor, then up, then a positive fixture request and its nearest
negative.