Skip to content

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> loopback for pair; required for authority What Authority binds its control plane and registration listeners on. Set a private address explicitly for --role authority. 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> unset Where the cluster's state lives.
--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 both files: Authority validates against it, and the Proxy advertises it to gdsgate connect. production refuses to start an Authority without it. Every separate --role proxy run needs these flags: OIDC is not inherited from an existing Authority file. A client bootstrapped from a Proxy with no [oidc] signs in against the built-in development issuer.
--control-keyring, --audit-keyring, --kms-key unset Keyrings already in place, and the external keys a wrapped reference names.
--authority-output, --proxy-output /etc/gdsgate/{authority,proxy}.toml Where each configuration goes.
--state-dir <dir> beside the Proxy configuration Persistent Proxy transport identity. Set /var/lib/gdsgate/proxy for a Linux service. 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 off Connectors register and renew at the join relay (50064) in place of the client port. For a gateway reached by IP address alone. 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, then the client, tunnel, WebSocket and relay listeners at fixed offsets. 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.

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. HA settings are applied after preparation: Proxy commands.

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 [proxy].public_join = true, [endpoints].authority_enroll [proxy].public_join = true, [connector].authority_transport = "tunneled" https://<domain>:50061
--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, which carries no name or address a node dials, and registration there is refused; config check --role proxy and doctor warn under proxy.public_join. A gateway reached by IP address alone uses --join-relay: the relay passes registration through 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 named, the run has the cluster CA issue the registration certificate. 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

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 bootstrap-admin, then [admin] in the Authority configuration same
4. Enroll the Proxy authority create-token --role proxy; write GDSGATE_ENROLL_TOKEN=<token> to proxy.env, mode 0600; systemctl enable gdsgate-proxy.service, systemctl start gdsgate-proxy.service authority create-token --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 for each resource, the catalogue row, then the connector that serves it same
7. Set up workstations gdsgate connect <domain>:<port> --fingerprint <sha256>, gdsgate login, gdsgate setup check --role client same

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 remove-resource to remove it. Removing an undeclared resource is not an error.
--authority-config, --proxy-config, --connector-config Linux: /etc/gdsgate/{authority,proxy,connector}.toml; Windows: %ProgramData%\gdsgate\{authority,proxy,connector}.toml Which files to edit.
--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.

--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 set-resource 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). A join with neither derives https://proxy.<domain>:50064, the relay on the default block; this is wrong for a moved block or for registration at Authority directly.
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 set-resource 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 bootstrap-admin, then [admin] in the Authority configuration same same
4. authority create-token --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 set-resource, 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 ls
# ? what you may reach. The catalogue is the cluster's: gdsgate ls

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.

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