Setup commands¶
Prepares, changes, restores and checks a deployment from flags. Global flags are in the CLI hub.
gdsgate setup prepare --domain <name> --security-profile <profile>¶
Write the Authority and Proxy configurations for this server in one run. Values both roles use are asked once. The Proxy is pointed at the loopback address Authority binds.
gdsgate setup prepare --domain gate.example.com --security-profile pilot \
--store-url postgres://gdsgate@127.0.0.1:5432/gdsgate \
--tls-cert /etc/letsencrypt/live/gate.example.com/fullchain.pem \
--tls-key /etc/letsencrypt/live/gate.example.com/privkey.pem \
--dry-run
| Flag | Default | Meaning |
|---|---|---|
--domain <name> |
required | The name clients dial. |
--security-profile <p> |
required | dev, pilot or production. |
--role <pair\|authority\|proxy> |
pair |
Which roles this machine gets. pair writes both. authority and proxy put the control plane and the gateway on separate machines; see below. |
--authority-host <host> |
unset | Where Authority answers, for --role proxy. Required there. The ports come from the port block. |
--authority-bind <addr> |
pair with SQLite: loopback; PostgreSQL or authority: locally owned IPv4 from --domain, otherwise required |
What Authority binds its control plane and registration listeners on. Automatic selection requires exactly one active local interface with that address. Set an explicit private bind for DNS, external LB/NAT addresses, IPv6 and saved bundles. Explicit values take priority. With pair, the Proxy dials Authority at this address; at a wildcard, on the loopback. |
--enroll-cert <path>, --enroll-key <path> |
unset | What Authority's registration listener presents. Off the loopback, production refuses to start without it. On a --role proxy run, naming the certificate writes https:// into [enroll].endpoint. The certificate is taken to be for --domain: where the Proxy dials another address, [enroll].transport_sni is set to the domain. Unset, with registration reached by IP address (--domain, --authority-bind or --authority-host an address) and a store named: the cluster CA issues it, see issued by the cluster CA. |
--store-url <url> |
dev: SQLite in the Authority state directory; otherwise required |
Linux: sqlite:///var/lib/gdsgate/authority/store.db?mode=rwc. Windows: store.db under %ProgramData%\gdsgate\state\authority. The service and administrative commands open the same file. pilot and production require PostgreSQL. |
--store-password-file <path> |
unset | store_password_file, for a URL that carries a user and no password. The password does not appear in the URL, the plan or the log. |
--oidc-issuer <url>, --oidc-client-id <id> |
unset | The identity provider people sign in at, and gdsgate's client ID there. Written into prepared role files: Authority validates against it, and the Proxy advertises its effective profile to gdsgate connect. production refuses to start an Authority without it. A separate preparation does not read an existing Authority file; authorized Proxy join saves the public profile. For existing files and extended settings, follow profile distribution. |
--control-keyring, --audit-keyring, --kms-key |
unset | Keyrings already in place, and the external keys a wrapped reference names. |
--authority-output, --proxy-output |
Linux: /etc/gdsgate/{authority,proxy}.toml; Windows: %ProgramData%\gdsgate\{authority,proxy}.toml |
Where each configuration goes. |
--state-dir <dir> |
Linux: /var/lib/gdsgate/proxy; Windows: %ProgramData%\gdsgate\state\proxy |
Persistent Proxy transport identity in the directory the service may write. This flag belongs to the Proxy role; Authority state follows its configured paths. |
--listen <addr>, --tls-cert, --tls-key |
see proxy init |
The Proxy's half. A connector registering on the client port checks --tls-cert for the name it dials. |
--join-relay |
selected for an IP gateway without --tls-cert, unless --no-public-join |
Connectors register and renew at the join relay (50064) in place of the client port. Authority's registration certificate verifies the IP address there. See connector route. |
--no-public-join |
off | Connectors register at Authority's own listener and take the direct route. See connector route. |
--save <dir>, --node <name> |
unset | Write a bundle for another machine; nothing on this machine changes. A bundle written on Windows carries no service files: on the target, run gdsgate service install <role> for each role after setup apply. |
--binary <path> |
this process, or /usr/local/bin/gdsgate for a bundle |
The program the systemd units name. Refused on Windows. |
--unit-dir <dir> |
/etc/systemd/system |
Where the systemd units go: an image root, or a directory from which root installs them later. Refused on Windows. |
--policy-output <path> |
beside the Authority configuration | Where the seed policy goes. |
--access-group <name> |
admins |
The identity-provider group the seed policy makes the cluster's owner. It replaces the baseline's placeholder admins in every rule: editPolicy, approvePolicyEdit, approveRequest, manageCatalog, revokeNode, disableUser, issueJoinToken, killSession, viewNodes, viewRecordings, and sessions on every lane. Rules the baseline keeps commented stay commented: forwarding, onward certificates, the client-key grant. rotateCA, enrollNode and viewAudit stay with the administrative certificate. That group grants everyone else access afterwards with authority policy edit. |
--port-base <port> |
50050 |
First port of the block: registration, control plane, client, tunnel, WebSocket, relay and paired HA peer listeners at fixed offsets. Range 1..=65520. Change it to run a second deployment on one machine. |
--metrics-port <port> |
9090 |
Where /healthz, /readyz and /metrics answer. Not part of the block. The pair's Proxy takes the next port, and so does --role proxy on a host whose authority.toml answers on this one. |
--start |
off | After writing, install and start the services: the control plane, an administrative identity, the Proxy's token, the Proxy. Needs root on Linux (systemctl start) or an elevated prompt on Windows (sc.exe start). The install step of setup --tui does the same. Not with --dry-run or --save. |
--dry-run, --json, --approve-plan '<reviewed-digest>' |
off | Show the plan; print it as JSON; refuse unless it is the plan that digest names. |
Both configurations are one plan with one digest. --dry-run creates
nothing, key material included.
Defaults apply to a new configuration. Repeating the original preparation with
its saved receipt retains existing files; an existing installation without a
matching receipt is refused. Use setup change to edit
installed settings. See retry after a failure.
Updating the binary keeps
the store URL and identity paths already written in those files. A custom
--state-dir or --store-url takes precedence over the platform defaults.
The public address does not determine a private bind or the address of a
separate Authority; those inputs remain explicit.
Start-up checks. The Authority configuration goes through the checks its
first start applies. Without --dry-run, a configuration they reject produces
no plan, and the refusal names the rule: [oidc].issuer unset under
production, [authority].enroll_cert_file naming no certificate under
pilot or production, a store_url that is not a postgres:// URL.
With --dry-run, the plan is printed after a to prepare section. Each line
is a profile matrix row the written files do
not satisfy, the flag that supplies it (or the key to set in the written file),
and what the first start does without it. The Proxy is judged as enrolled.
Under pilot and production, a Proxy without --tls-cert/--tls-key is
listed as not refused: it presents its enrolled identity, which clients trust
through gdsgate connect. The dry run exits 1 when a listed item is refused
at start. --json carries the list as to_prepare: what, how, at_start.
== to prepare for `pilot` ==
x: `store_url` names PostgreSQL (unset or `sqlite://` is SQLite): --store-url (refused at start)
x: Registration listener TLS: `[authority].enroll_cert_file` and `enroll_key_file`: --enroll-cert, --enroll-key (refused at start)
! `[audit].export_path`: in /etc/gdsgate/authority.toml, `[audit].export_path = "/var/lib/gdsgate/authority/audit.jsonl"` (Windows: `%ProgramData%\gdsgate\state\authority\audit.jsonl`), shipped by a log collector (warning at start)
x: `[enroll].endpoint` scheme is `http://`: --enroll-cert (refused at start)
! `[proxy].public_cert_file`, a certificate clients already trust: --tls-cert, --tls-key (not refused at start)
What is written.
| Platform | Changes, in order |
|---|---|
| Linux | Two keyrings, two configurations, two systemd units. The units carry the hardening of packaging/systemd with the binary and configuration paths filled in. Installing a unit needs root: without it the run stops after the four files and exits 5. |
| Windows | Two keyrings, two configurations. The services are registered by --start, or by gdsgate service install <role> from an elevated prompt; the plan lists them as unchecked. |
Seed policy. A cluster with no stored policy runs the deny-all bootstrap,
and policy push cannot reach it. The first policy is a file named by
[policy].path; Authority stores it as version 1 on its first start. The file
is the shipped baseline with admins replaced by
--access-group. It grants connect and sshProgram on SSH hosts. Forwarding,
onward certificates and sshUseClientKey stay ungranted. The break-glass permit
is unchanged.
The --domain flag remains required when preparing a Proxy beside an
existing Authority. It names the public gateway entry; --role proxy prepares
only the Proxy and reuses the supplied Authority trust. A new PostgreSQL
Authority starts with HA and keyring sync enabled. Its paired Proxy derives an
individual peer address. Additional roles use join; current Authority
membership refreshes automatically.
The first PostgreSQL Authority has a permanent ha.owner and seeds its own
HTTPS control endpoint in ha.authority_peers. It initializes the canonical
material once. A later host needs an owner-bound bootstrap permission; reusing
the database URL cannot initialize a second cluster over existing material.
SQLite remains standalone, and existing configurations retain their settings.
Publication. New Authority configurations explicitly select
discovery.publication = "auto". Newly admitted Connector identities publish
ordinary configured backends within their assigned namespace and scope. Existing
files with no field remain manual, and an existing shared policy wins on restart.
Change the enrollment policy with authority publication set; existing nodes
keep their assigned mode. See manual resource assignments.
Minimum inputs. A pair requires the public address and security profile.
dev supplies a persistent SQLite store. pilot and production require
PostgreSQL and an individual Authority bind, inferred from a locally owned IPv4
public address or supplied with --authority-bind; production also requires
OIDC and the configured key providers.
An identity provider is always entered as an issuer/client ID pair.
For Authority alone, the public IPv4 address can also provide the bind when it is assigned to exactly one active interface on this server:
gdsgate setup prepare --role authority --domain "$NODE_IP" \
--security-profile pilot --store-url "$STORE_URL" \
--oidc-issuer "$OIDC_ISSUER" --oidc-client-id "$OIDC_CLIENT_ID" \
--start
Run --start as root or from an elevated Windows prompt. Here NODE_IP
must belong to this server. When clients dial an external LB or NAT address,
pass --authority-bind "$PRIVATE_IP" as well. DNS names are not resolved to
choose an interface. A saved bundle always requires its target's bind;
interfaces on the preparing host do not choose it.
In setup --tui, enter OIDC on the Cluster step for any role. A Proxy-only
installation writes that provider into its configuration. The wizard runs
only when explicitly requested; missing CLI inputs name the required flag.
Bind and advertised addresses. The Proxy binds 0.0.0.0:<port>. The
Authority's [endpoints] holds what a node is told at registration and at every
renewal, and carries the deployment's name. A node told 0.0.0.0 or
127.0.0.1 cannot reach the gateway.
Connector route¶
| Flags | Proxy file | Authority file | Connector --enroll-endpoint |
|---|---|---|---|
| none, DNS name or supplied public certificate | [proxy].public_join = true, [endpoints].authority_enroll |
[proxy].public_join = true, [connector].authority_transport = "tunneled" |
https://<domain>:50061 |
| none, IP without a public certificate | [endpoints].proxy_join, authority_enroll |
[endpoints].proxy_join, authority_transport = "tunneled" |
https://<IP>:50064 |
--join-relay |
[endpoints].proxy_join, authority_enroll |
[endpoints].proxy_join, authority_transport = "tunneled" |
https://<domain>:50064 |
--no-public-join |
neither | neither: route direct |
https://<authority-bind>:50050 |
On tunneled, Authority tells a registering node no Authority address and a
renewal address on the gateway: the client port, or the join relay when one
is bound. A connector joins with no --route.
The client port presents --tls-cert. Without it, the Proxy presents its
enrolled identity. Verified discovery can register through public_join using
the accepted CA and proxy.gdsgate.internal. An explicit registration URL needs
that TLS name and trust supplied separately; checking the public IP or domain
against an enrolled identity fails. See public join
for the current diagnostic warning on this configuration.
An IP gateway without --tls-cert selects the
relay automatically; --join-relay selects it explicitly. It passes registration to Authority's
registration listener, whose certificate carries the address.
Issued by the cluster CA¶
With registration reached by IP address, no --enroll-cert and a store
configured, the run has the cluster CA issue the registration certificate.
This includes the default persistent store under dev. Not
with --save: a bundle carries no key material.
| Written | Value |
|---|---|
Authority, [authority] |
enroll_cert_from_cluster_ca = true; enroll_cert_file, enroll_key_file in Authority's state directory: /var/lib/gdsgate/authority/enroll.pem, enroll.key (Windows: %ProgramData%\gdsgate\state\authority\) |
Proxy, [enroll] |
endpoint = "https://<authority address>:50050", transport_ca = transport-ca.pem beside proxy.toml |
| After the files | the pair, issued from the cluster CA; the cluster CA in transport-ca.pem |
The certificate carries the addresses in Authority's [endpoints], the
loopback where registration is bound there, and enroll.gdsgate.internal.
It is valid 90 days. Authority issues it again at start and hourly while it
runs when it expires within 30 days, lacks an address, or was issued by a CA
that is no longer the active one; see
enroll_cert_from_cluster_ca.
Connectors pin the cluster CA by transport_ca.fingerprint, the value
clients get:
gdsgate join 203.0.113.10 --enroll-endpoint https://203.0.113.10:50064 \
--enroll-fingerprint <transport_ca.fingerprint> --serve <id>=ssh connect
On two machines, the control-plane run writes transport-ca.pem beside
authority.toml. Copy it beside the gateway's proxy.toml before the gateway
run; that run then writes https:// and names it.
The two halves on two machines¶
--role splits the pair. Run the command once on each machine, the control
plane first: the Proxy's enrollment token is issued there.
# on the control plane, at 10.0.0.5
gdsgate setup prepare --domain gate.example.com --security-profile pilot \
--role authority --authority-bind 10.0.0.5 \
--store-url postgres://gdsgate@127.0.0.1:5432/gdsgate \
--enroll-cert /etc/gdsgate/enroll.pem --enroll-key /etc/gdsgate/enroll-key.pem
# on the gateway
gdsgate setup prepare --domain gate.example.com --security-profile pilot \
--role proxy --authority-host 10.0.0.5 \
--enroll-cert /etc/gdsgate/enroll.pem \
--tls-cert /etc/letsencrypt/live/gate.example.com/fullchain.pem \
--tls-key /etc/letsencrypt/live/gate.example.com/privkey.pem
Each run writes its own machine's configuration and, on Linux, its own unit.
The control-plane run also writes the seed policy and the keyrings. An argument
for the other machine is refused: --store-url on a gateway, --tls-cert on a
control plane. A gateway run prints no cluster summary; the transport CA
fingerprint comes from the control-plane run.
With --no-public-join, --authority-bind is also the address Authority
hands to every joining node, so it must be the address other machines reach
it at, and a wildcard is refused: with 0.0.0.0 the Proxy still enrolls, and
the first connector is refused for lack of an address. On tunneled no
address is handed out.
The two runs agree on the route: pass --join-relay or --no-public-join to
both, or to neither. The control-plane run prints the gateway command with
the flag.
In a split install the registration listener crosses a network and carries
one-time tokens.
Name --enroll-cert/--enroll-key on the Authority run and --enroll-cert on
the gateway run; that writes https:// into [enroll].endpoint. Without it the
plan warns that the token crosses in cleartext, and production refuses. Reach
the control plane and the registration listener over a private network, or
restrict them with a firewall to the cluster's machines.
A completed run prints the JSON summary authority init prints, including
transport_ca.fingerprint. Every workstation needs that value; pass it out of
band.
Without --start, the run ends by printing the remaining steps in order, and a
line saying none of them has been done or checked:
| Step | Linux (as root) | Windows (elevated prompt) |
|---|---|---|
| 1. Give the services access to their files | create the gdsgate group and give it the configuration directory |
done by service install |
| 2. Start the control plane | systemctl enable gdsgate-authority.service, systemctl start gdsgate-authority.service |
gdsgate service install authority, sc.exe start gdsgate-authority |
| 3. Take an administrative identity | authority identities bootstrap --role admin, then [admin] in the Authority configuration |
same |
| 4. Enroll the Proxy | authority tokens create --role proxy; write GDSGATE_ENROLL_TOKEN=<token> to proxy.env, mode 0600; systemctl enable gdsgate-proxy.service, systemctl start gdsgate-proxy.service |
authority tokens create --role proxy; write the token alone to proxy.token, which the Proxy configuration names; gdsgate service install proxy, sc.exe start gdsgate-proxy |
| 5. Check the host | gdsgate doctor |
same |
| 6. Add resources | start the admitted Connector; automatic publication creates its qualified resources. Manual enrollment requires catalog rows and serving assignments first | same |
| 7. Set up workstations | gdsgate connect <domain>:<port> --fingerprint <sha256>, gdsgate login, gdsgate setup check --role client |
same |
Retry after a failure¶
Repeat the original setup prepare command. The CLI
saves a local receipt beside the first configuration before writing deployment
files: authority.toml.prepare.json for a pair or Authority,
proxy.toml.prepare.json for a Proxy. The receipt contains paths and hashes of
the intended files. It contains no credentials or private keys.
The retry writes missing files and keeps existing files, including comments and
manual settings. Different preparation inputs are refused; use setup change
to edit installed settings. An existing configuration without a receipt is
also refused. A lock prevents two preparations from applying simultaneously.
--dry-run creates no receipt or lock; --save writes a complete bundle for
the target host. The TUI Apply action uses the same preparation receipt and
lock. Repeat Apply with the original answers after a failure. Save carries
the selected roles and defers keyring creation to the target host.
With --approve-plan, review the retry plan and approve its current digest.
You can add --start to the original command. It reuses the administrative
identity, the Proxy's saved enrollment token or its enrolled identity. Running
services are left running. A failed start keeps the files for another retry.
A valid registration TLS certificate and key are reused; a pair due for renewal
is renewed under the existing cluster CA.
The CLI records completed cluster initialization in authority.initialized.json
using public CA key hashes, and Proxy enrollment in proxy.enrolled.json.
Lost keyrings, a missing initialized CA, or missing or incomplete identities require recovery. A retry
does not issue replacement identities for them. A store with a different CA is
also refused. Overlapping CA generations are accepted; after a migration that
removes all previously recorded generations, use service install with the
saved configuration. If an unused enrollment token expires, replace that token explicitly before retrying.
A connector is admitted only for catalogue rows that already exist. A connector
declaring another resource has its tunnel closed, and the error does not name
the resource. gdsgate join prints the rows its --serve entries need before
it uses the token.
Preparing for another machine. With --save, the bundle carries the two
configurations and the instruction to create the keyrings; it carries no key
material. Whether a keyring already exists is checked on the target: the plan
lists it as unchecked. On the target, setup apply --bundle creates the
keyrings from the Authority configuration in the bundle.
# on the workstation
gdsgate setup prepare --domain gate.example.com --security-profile pilot \
--save ~/setup/gate-01 --node gate-01
# on gate-01, after copying the directory
gdsgate setup apply --bundle ~/setup/gate-01 --dry-run
gdsgate setup apply --bundle ~/setup/gate-01 --approve-plan '<reviewed-digest>'
gdsgate setup change¶
Change settings of a running deployment. Only the named keys are rewritten; comments, ordering, secret references and other keys stay as they were. The file keeps its mode and owner on Linux and its ACL on Windows.
# review, then apply the plan that was reviewed
gdsgate setup change --public-port 8443 --dry-run
gdsgate setup change --public-port 8443 --approve-plan '<reviewed-digest>'
# a second resource on the node that serves it
gdsgate setup change --serve prod-db=postgres@192.0.2.40:5432
# a kind the compact form cannot spell: the declaration and the rest of it
gdsgate setup change --serve shop=web --backend shop:url=https://shop.example.com
# one setting of a resource that is already declared
gdsgate setup change --backend prod-db:statement_timeout_ms=30000
| Flag | Default | Meaning |
|---|---|---|
--public-port <port> |
unset | The port clients dial. Written to two files: the Proxy's bind and the Authority's [endpoints].proxy_public, which nodes and clients are given. |
--tls-cert <path>, --tls-key <path> |
unset | What the client-facing listener presents. |
--serve <id>=<kind>[@<addr>] |
none | A resource to add to what this node serves; repeat for more. Every kind is accepted, unlike gdsgate join; what the triple cannot express goes in --backend. The kind's address key (addr, api_url, url or allow) must come from the triple, a --backend, or the entry already in the file. The plan names the catalogue row it needs. |
--backend <id>:<key>=<value> |
none | One setting of one declared resource; repeat for more. Typed as in the file: yes/no is a boolean, digits are an integer, commas make a list. An empty value removes the key. Tables, arrays of tables and maps (routes, db_roles, cage and similar) cannot be edited this way and are left unchanged. @<path> and @- read a value as --set does. |
--set <file>:<section>.<key>=<value> |
none | One setting of a role file (authority, proxy or connector); repeat for more. Covers the rest of those files: ports, listener certificates, the identity provider, admission limits, rotation cadence. Typed as --backend; an empty value removes the key. A key with no section is at the file root (store_url); a missing section is created. @<path> reads the value from a file and @- from standard input; the plan does not print it. Use these for secrets, which other accounts on the host can see on a command line. @@ starts a value with @. |
--replace |
off | Let --serve rewrite an existing declaration. Without it, a --serve for a resource declared as something else is refused. |
--unserve <id> |
none | A resource this node stops serving; repeat for more. The declaration is removed from the file. The catalogue row stays; the plan names gdsgate authority resources remove to remove it. Removing an undeclared resource is not an error. |
--authority-config, --proxy-config, --connector-config |
Installed role configuration | Explicit paths override discovery. Multiple installed paths require the corresponding flag. |
--checkpoint-dir <dir> |
.checkpoints beside the first file changed |
Where copies of the replaced files are kept. gdsgate setup restore reads them from its --from directory; pass the same directory there if you change it here. |
--dry-run, --json, --approve-plan '<reviewed-digest>' |
off | Show the plan; print it as JSON; refuse unless it is the plan that digest names. |
--restart |
off | After writing, restart the services that read the changed files. Linux: systemctl restart, as root. Windows: sc stop, then sc start, from an elevated prompt. Refused with --dry-run. |
Without these path flags, setup change uses the same installed role records as
service install and daemon commands. It discovers only the roles needed by the
requested changes. Standard platform files remain discoverable. The selected
client cluster does not choose local files to edit.
# Change the Connector registered by setup or join.
gdsgate setup change --backend demo-web:url=http://127.0.0.1:8000 --dry-run
# Choose a specific installation when several Connectors are registered.
gdsgate setup change --connector-config /etc/gdsgate/connector-ha.toml \
--backend demo-web:url=http://127.0.0.1:8000
Changes retain other settings, comments, credential references and file access
permissions. Repeating an applied change produces no file writes and returns exit code 3
(already present). Review with
--dry-run; omit it to apply the change and save a checkpoint.
--public-port changes both the Proxy bind and the Authority's
[endpoints].proxy_public in one plan. It does not change the firewall or
workstations that hold the old port; on each workstation run
gdsgate connect <domain>:<new port>.
Adding a resource writes the node's configuration only. The plan names the
gdsgate authority resources set row to write, as gdsgate join does; the
connector is admitted for the resource once that row exists.
All changes to one file are one write, and its checkpoint holds the file as it was before the run.
Without --restart nothing is restarted, and the run ends by printing the
restart command: systemctl restart ... on Linux, Restart-Service ... on
Windows. Exit codes are the setup contract, plus 3
when every change was already in place.
gdsgate setup --tui¶
Opens the full-screen wizard. It opens only with this flag; gdsgate setup
with no sub-action prints usage and exits non-zero. The wizard runs the same
operations as the sub-actions above.
The first step chooses the task; the rail on the left then shows that task's
steps. Apply writes a deployment on the install track; on the change and
restore tracks the same step is Result, the report of the last change or
restore.
| I am here to | Steps |
|---|---|
| install a new deployment | Task → Cluster → Authority → Proxy → Draft → Apply → Settings → Check |
| change one setting in an installed file | Task → Change → Settings → Result → Check |
| restore a file from a checkpoint | Task → Restore → Result → Check |
| declare a resource on a connector node | Task → Cluster → Connectors → Access → Check |
| set up a client on this workstation | Task → Cluster → Client → Check |
Each step shows a label, its value, and one line describing the field. ?
opens the long form at the bottom: what the step writes and the full text of
the current field. Press ? again to close it.
Each step has one action, shown in the key line with its letter:
a write the files on Apply, s write a bundle on Draft, c make the change,
r put it back, w write the changes on Connectors and Settings. A step with
no action shows n next. On a narrow screen the key line drops its least used
entries first; the action, ⏎ and the exit stay.
b and n go back and next from either pane. The key line shows what ⏎ does
on the current row: ⏎ open or ⏎ close on a tree node, ⏎ edit on a typed
value, ⏎ next where there is nothing to answer. A choice is changed with ←→
and has no ⏎. Esc steps back on the rail, closes an open tree node, crosses
from the body to the rail, and leaves a field as typed. q exits.
On the Task step, ↑↓ moves through the five tasks and selects one; the rail
shows that task's steps. On the install task, a second answer chooses the roles
this host runs: authority + proxy, authority or proxy.
Two lines under the list show what the task would write here and what the host
survey found. v opens the full survey: files written on this host with their
paths; what is needed from elsewhere (the host in endpoints.authority, the
enrollment token, authority.enroll_cert_file); what this task does not ask;
missing answers; where configurations were looked for; one line per role.
The role steps take the answers a configuration is written from. The Settings step, once the file exists, shows every key in it.
Each role step has a field for the path of its configuration file. When the survey found one, including the file a running role was started with, the field starts with that path, and the draft, change and checkpoints use it. A field that belongs to the other host's file is marked as such. Missing answers are listed with the step that takes each.
On Windows the survey does not read running processes, service state or the resident client; those lines report that they could not be read.
| Group | Step | What it does |
|---|---|---|
| Cluster | Cluster | Keys written into both role files: the external name, the security profile, the port block, the registration route, and the group the seed policy makes the cluster's owner. Each track asks only what it uses; the rest is marked as already in the installed files. Registration route is proxy join relay (port base +14, bound only with --join-relay) or authority enroll listener (port base +0). Without an explicit --enroll-endpoint, join reads the verified public bundle at the supplied address (default port 50061). Only an advertised registration capability selects the route; a relay or direct Authority route without it needs an explicit endpoint. |
| Start | Task | The five tasks. v adds one line per role: whether a configuration declares it and by which key, what the service manager says, which processes run it, whether a resident client runs, and the file that declares it. A final line says whether any role is serving has not been checked. A role counts as configured only when a key is written; defaults do not count. Configurations are looked for in the file each running role was started with, then /etc/gdsgate, ~/.gdsgate, and the directory of a --config passed to the wizard. With v closed: what the task would write here, and how many roles are configured and running. |
| Cluster | Authority | authority.toml: store_url and store_password_file, [oidc].issuer and [oidc].client_id, the output path, the systemd unit directory (Linux), and authority.enroll_cert_file / enroll_key_file; for a split install, the interface endpoints.authority binds. v adds an existing control or audit keyring and policy.path. An Authority under production with no provider, or under pilot with no registration certificate, refuses to start. |
| Cluster | Proxy | proxy.toml: the output path, proxy.public_cert_file and its key, proxy.public_join, and the host in endpoints.authority for a split install. v adds the interface in endpoints.proxy_public (the port comes from the block) and enroll.state_dir. |
| Resources | Connectors | Every [[connector.backends]] entry on this host, plus drafts, as a tree. A node row shows id, kind, address (addr, url, api_url or allow) and its file, or new. Above the tree: for a running connector, what it reports over its control socket: resources admitted at its last registration, resources withheld and why, resources refused where the file and the catalogue disagree. → or ⏎ opens a node, ← or Esc closes it; ⏎ edits a setting, ←→ changes a choice. The band under the body shows the cluster's last word on the row, or its file. An open node shows its kind's required settings; v shows all. Tables, arrays of tables and maps (routes, db_roles, windows_users) are listed and left unchanged. a adds a node, d marks one for removal, w writes the changes: one plan and one checkpoint per file. A draft is not written here: the step prints the gdsgate join to run on the serving node, the authority resources set row, and, for a kind the compact <id>=<kind>[@<addr>] cannot express, the [[connector.backends]] entry to pass as --backends-file. |
| Resources | Access | A group, and the Cedar policy an SSH session needs: connect opens the session, sshProgram covers every shell, exec and subsystem. SSH only; a resource on this host with another kind is flagged here. The policy is printed, to be written with gdsgate authority policy edit. |
| Workstation | Client | The gdsgate connect, gdsgate login and gdsgate setup check commands for this deployment, and what this host already has. |
| Write | Draft | The plan for the answers given. s writes a bundle for another host; a on the next step applies it here. v adds two answers a bundle needs: the gdsgate path on the target host (the Linux unit names it) and telemetry.metrics_listen. |
| Write | Apply | The report of what was applied, and what is left. As root on Linux or elevated on Windows, the action is a write and start: see the table below. Each step gets ✓ or ✗ when it returns. While waiting for the control plane the count of seconds is shown; on timeout the step names the service state and its last logged error. Apply stops at the first refusal, names what was done, what refused and what was not attempted, and exits with the setup contract's code. Without the privilege, the files are written, nothing is started, and the remaining steps are printed; s on Draft writes them as a bundle. Steps on other machines (a connector's join, a workstation's connect) are always printed. |
| Write | Check | What this host reports without asking the cluster: one line per role (configuration, service manager, processes), then the client. Re-read after each apply; the doctor command it prints carries the path this run used. |
| Installed | Change | One key of an installed file: endpoints.proxy_public, the TLS pair, a [[connector.backends]] entry. c writes it after a checkpoint. As root or elevated the action is c change and restart: the services that read the changed files restart and their sessions end; the plan says so first. |
| Installed | Settings | Every key of a role file, as a tree: the file at the root, one group per section ([endpoints], TLS material, the state backend, [oidc] and [identity], [policy], [enroll], proxy capacity, proxy admission control, the proxy join relay, the proxy browser entry, [ca_rotation] and [ha], [telemetry]), one row per key inside. ↑↓ moves, → opens a group, ← closes it (from a key, goes up to its group), ⏎ edits a value, ←→ on the root selects the file, w writes the changed keys. Keys no group lists are shown in a last group of their own. |
a write and start (and setup prepare --start) runs these steps after writing
the files:
| Step | Linux (root) | Windows (elevated prompt) |
|---|---|---|
0. Every listener and [telemetry].metrics_listen of the roles not yet running is free, and no two keys share an address |
bind and release each address | same |
1. service install authority |
unit file, gdsgate group, file modes, systemctl daemon-reload |
service registration, file access for the service account |
| 2. Start the control plane and wait until it answers | systemctl start gdsgate-authority.service |
sc.exe start gdsgate-authority |
3. authority identities bootstrap --role admin, then [admin] in the Authority configuration |
same | same |
4. authority tokens create --role proxy |
token saved as proxy.env |
token saved as proxy.token |
5. service install proxy, start the Proxy and wait up to 60 s for its /readyz |
systemctl start gdsgate-proxy.service |
sc.exe start gdsgate-proxy |
A Proxy that does not report ready fails step 5 with the last five lines it
logged. Step 0 refuses with the key, the address and the file, for example
cannot bind `[telemetry].metrics_listen` = 127.0.0.1:9090: Address in use;
nothing is started and a Proxy's token is not spent.
| Installed | Restore | The checkpoints on this host, the plan for writing one back, and r to do it. |
The rail on the left chooses the step; the body on the right works on it. The pane that has the keys shows its current line reversed, and the key line at the bottom belongs to that pane.
| Key | On the rail | In the body |
|---|---|---|
↑ ↓ |
move between steps | move between fields or list entries, or scroll a report |
← → |
→ crosses into the body |
move through a field's choices; ← crosses back. Inside a value they move the caret and stop at its ends |
↹ |
cross to the body | cross back to the rail |
⏎ |
nothing | the action shown in the key line: open or close a tree node, enter or leave a field (letters typed into a value are not commands), or go on where there is nothing to answer. A choice takes ←→ and has no ⏎ |
Home End Delete |
nothing | inside a value: to its start, to its end, delete the character under the caret |
Esc |
back to the step before | close the open tree node, then cross back to the rail |
b n |
back and next along the track, from either pane | |
^← ^→ |
scroll a line wider than the screen; lines are not wrapped, and a cut value is shown in full under the frame | |
→ ← on a tree |
on Connectors and Settings: open the node, close it (from a leaf, go up to its node). On a leaf that is a choice, ←→ change the value |
|
a d w |
on Connectors: add a node, mark the current one for removal from its file (or drop a draft), write the changed entries | |
v |
toggle between all settings of the step and the required ones: an open resource's kind, or the answers of the Cluster, role and Draft steps | |
s a c r w |
the step's action (write a bundle, apply, change, restore, write the changed entries), from either pane | |
? |
the long form of this step and the current field; again to close it | |
q |
exit |
Marks are the command line's: + a change, ! its cost, ? not checked,
✓ done, ✗ refused. Colour repeats the mark: green for done, orange for a
consequence, red for a refusal. NO_COLOR turns colour off and changes nothing
else.
Two lines above the bottom rule describe the current row and, when its value was cut, show it in full. They stay empty when there is nothing to show.
A form's answers sit in a fixed frame. The field being edited is marked ✎, the
caret is a reversed column, and a value longer than the frame scrolls inside it.
Cut values end in an ellipsis; the current one is shown in full under the frame.
The wizard exits with the setup contract's code for the
last thing it applied: 0 when everything was applied, 5 when part of it was.
Layouts are drawn for 80 columns. From 60 to 79 columns the rail folds into the context line. Below 60 columns or 10 rows the wizard says so and exits, including when the window is resized while it is open.
gdsgate setup restore¶
Restore files a change replaced. Before replacing files, setup change saves
their content and mode to an owner-only .checkpoints directory beside the
first of them. setup restore writes them back.
gdsgate setup restore --list
gdsgate setup restore --dry-run # the newest checkpoint
gdsgate setup restore --approve-plan '<reviewed-digest>'
| Flag | Default | Meaning |
|---|---|---|
--from <dir> |
/etc/gdsgate/.checkpoints on Linux, %ProgramData%\gdsgate\.checkpoints on Windows |
Where the checkpoints are. |
--checkpoint <name> |
the newest | Which one, by the name of its directory. |
--list |
off | List what is kept and stop there. |
--over-a-later-edit |
off | Restore a file that was edited after the change, discarding that edit. |
--dry-run, --json, --approve-plan '<reviewed-digest>' |
off | Show the plan; print it as JSON; refuse unless it is the plan that digest names. |
--restart |
off | Restart the services that read the restored files, as setup change --restart does. Refused with --dry-run and --list. |
When a new checkpoint is taken, the oldest beyond twenty are removed. Nothing else removes them.
Only files are restored. A catalogue row, a policy, an identity, a certificate
authority, a revocation and the activation epoch are reverted with a new change:
authority resources set,
authority policy push.
The plan names what cannot be restored before anything is written: a file edited
since the change (left alone unless --over-a-later-edit), a saved copy this
binary would not start with, a file the change created. Without --restart
nothing is restarted, and the run ends by saying so.
gdsgate setup check [--role client]¶
Report what is set up on this machine and what is missing. It makes no network connection and works without a route to the gateway.
gdsgate setup check --role client
# installation https://gate.example.com:50061
# ✓ trust anchor ~/.gdsgate/ca.pem
# ✓ signed in as alice@example.com at https://idp.example.com/realms/gdsgate
# the identity is good for 7h
# ? which groups this cluster resolves you into ... gdsgate resources list
# ? what you may reach. The catalogue is the cluster's: gdsgate resources list
A gateway gdsgate connect wrote without [client].transport_ca has a
publicly issued certificate; its line is ✓ trust anchor: this host's trust
store. Group membership and the catalogue are decided by the cluster. Both
are shown as ? with the command that reports them.
--json prints the same lines with the marks spelled as words.
gdsgate setup apply --bundle <dir>¶
Apply a prepared bundle on the host it was written for.
gdsgate setup apply --bundle ~/setup/gate-01 --dry-run
gdsgate setup apply --bundle ~/setup/gate-01 --approve-plan '<reviewed-digest>'
The bundle's files are checked against its report, then the node name. The plan is then rebuilt against this host; approvals from the preparing run do not carry over.
A bundle writes only to absolute paths of .toml, .cedar, .service and
.keys files, and reads only files inside its own directory. A bundle naming
anything else is refused before a plan is built. As root on Linux or from an
elevated prompt on Windows, --approve-plan is required: run --dry-run first
and approve the digest it prints.
Before the first approved write, apply saves <first-config>.bundle.json beside
the Authority configuration, or the first role configuration when there is no
Authority. A matching receipt makes a retry keep existing files, including
manual settings, and write missing files. Review the retry plan with --dry-run
and approve its new digest. Paths and hashes in the receipt identify the
original preparation; a different bundle recipe is refused. No credentials or
private keys are copied into the receipt.
The first approved apply can replace an existing file as shown in its plan. Repeat apply refuses changed identity/storage references and lost keyrings. The bundle and node checks run on every retry. The receipt lock prevents simultaneous application. Preview and approval failure create no receipt. Apply prepares files and keyrings; it does not start services or initialize a cluster CA. If a local preparation recorded an initialized CA, apply also checks that it is still in the saved store before writing files.
| Flag | Meaning |
|---|---|
--bundle <dir> |
The directory --save wrote. |
--approve-plan '<reviewed-digest>' |
Refuse unless the plan rebuilt here is the one that digest names. Required as root or elevated. |
--target-is-this-host |
Go ahead although the bundle names another node, or this host's name cannot be read. |
--dry-run, --json |
Show the plan; print it as JSON. |
Exit codes, shared by every command that applies a plan:
| Code | Meaning | What to do |
|---|---|---|
0 |
applied in full | - |
1 |
nothing applied | read the refusal |
4 |
the plan no longer matches what is there | prepare again and review |
5 |
some steps are done, one refused | continue from where it stopped |
gdsgate setup kubernetes configure¶
Configure one cluster in the installed Connector configuration. Use --config
for a different file. The command edits existing backend/source tables,
preserves other resources and comments, and saves a checkpoint before applying.
It starts no service and makes no API or Authority call.
| Purpose | Generated declarations |
|---|---|
api |
Kubernetes API backend; no discovery source |
discovery |
Discovery source; no Kubernetes API backend |
both |
API backend and discovery source |
The ID identifies both declarations locally. Reusing the ID updates its purpose;
changing from both to discovery removes its API backend. A conflicting kind
or duplicate ID is refused before writes. An existing inline Kubernetes probe
moves to the discovery source, retaining its filters and polling interval.
Before configuring discovery, obtain the Connector's Registry UUID from
authority nodes list and match it to the node column in authority scopes list.
For an automatic Connector, use its assigned prefix, such as conn-k8s/.
For a manual Connector, have the administrator create an explicit scope first.
The source ID and scope prefix are different values; setup does not allocate a
namespace. See publication modes.
Inside a Pod, with its ServiceAccount token mounted:
DISCOVERY_SCOPE='<assigned prefix from authority scopes list>'
gdsgate setup kubernetes configure inventory \
--purpose discovery --scope "$DISCOVERY_SCOPE"
Setup derives the HTTPS API address from KUBERNETES_SERVICE_HOST and
KUBERNETES_SERVICE_PORT_HTTPS (default 443). The CA and token paths use the
standard ServiceAccount mount. Set automountServiceAccountToken: true or
provide a projected token and explicit paths. Discovery needs list rights;
API access additionally needs impersonation rights.
Outside Kubernetes, select a context explicitly:
gdsgate setup kubernetes configure production \
--purpose both --context production --scope "$DISCOVERY_SCOPE" \
--token-path /etc/gdsgate/kubernetes-api.token \
--discovery-token-path /etc/gdsgate/kubernetes-discovery.token
Local kubectl config view reads the selected context from ~/.kube/config;
--kubeconfig PATH selects another file. Setup reads the API address, public CA,
and tokenFile reference. Embedded CA data is saved beside the Connector config
under a content-derived filename. Credentials, client keys, inline tokens and
credential plugins are not imported. Provide a ServiceAccount token path when
the context has none. Token files remain referenced and are reread by Connector,
including projected token rotation. A context disabling TLS verification is refused.
Existing addresses, CA/token references and discovery settings take priority over
inferred defaults. Override them with --api-url, --ca-path, --token-path
and --discovery-token-path. Different API and discovery credentials remain
separate on subsequent runs. Discovery-only can use platform TLS roots when no
CA is named; API access requires a CA path.
--scope names the publication boundary already authorized by Authority. Setup
does not create that grant or a manual API catalog resource. A new source defaults
to Services with selector gdsgate.io/expose=true; use --sources service,pod,node
and --label-selector SELECTOR to change them. Existing selectors are retained.
Review with --dry-run; use --json for the plan and --approve-plan DIGEST
to require that same plan on apply. Drift stops writes. An unchanged invocation
returns exit 3. After applying, restart Connector and check its discovery and
resource status. setup restore restores the configuration checkpoint; a newly
imported public CA can remain as an unused file.