vike-cli backend
Mint a vike-tradehub node's authentication keys on the daemon's own box with `backend setup`, then attach a client machine to a running node with `backend connect`, `status`, and `disconnect`.
vike-cli backend stands a vike-tradehub node's authentication up on the machine running it, and attaches a separate client machine to a node that is already running. It has two halves, and each runs on a different box — getting that right is the one thing to know before typing anything else:
backend setupruns on the daemon's box — the machine actually runningvike-tradehub. It mints two keys, writes them into that box's own store, and never prints a key value.backend connect,backend status, andbackend disconnectrun on the client's box — a laptop, a container, anywhere that wants to reach the daemon. They raise or close an SSH tunnel, take the two keyssetupminted, and prove the connection with a real round trip against the node.
"Node" means the running vike-tradehub daemon: one process holding the live core, its venue mounts, and its authenticated socket. It is not Node.js and it is not rented compute — the word survives in the protocol (--node, the node.env file) even though the verb itself was renamed from vike-cli node to vike-cli backend, because "node" read as something else to people arriving from outside this codebase.
No subcommand here can print, log, or journal a key value, on any path. What reaches the screen instead is each key's key_id — a derived, non-reversible fingerprint (crates/vike-cli/src/cmd/node/mod.rs's key_id) that is safe to paste anywhere. Comparing the two ids setup printed on the daemon's box against the two connect or status print on the client's box is this design's whole answer to "did I just attach to the right node."
Usage
vike-cli backend setup [--addr HOST:PORT] [--control] [--rotate]
vike-cli backend connect HOST [--port N] [--manual] [--no-tunnel] [--replace]
vike-cli backend status
vike-cli backend disconnect [--port N]A flag scoped to the other box is refused by name rather than silently dropped — --control on connect, or --manual on status, fails immediately and says which box the flag belongs on (crates/vike-cli/src/cmd/node/mod.rs's check_flag_scope). That matters most for --control: silently accepted on the wrong box, it would leave an operator believing the daemon's write channel was armed when nothing armed it.
setup — on the daemon's box
Mints both node keys from the OS CSPRNG (32 bytes each, hex-encoded), writes them into this box's store, sets the bind address, and prints each key's id plus a restart line. Run it once, on the machine actually running vike-tradehub:
vike-cli backend setupNothing here accepts a key, on any path
setup mints both keys itself — there is no argv form, no stdin form, and no --from-env form to refuse, because there is no operator-supplied value to accept. The one path on which a human ever touches key material is connect --manual, and only there.
The default bind address is 127.0.0.1:7879. To bind somewhere else and arm the write channel in one step:
vike-cli backend setup --control --addr 0.0.0.0:9100--control is never the default and never inferred
flags.tradehub_control is written only when --control is passed. A box with fresh keys and no --control mints the control key but never writes flags.tradehub_control, so nothing on the daemon side has been told to trust it — run setup --control once you mean to arm the write channel (crates/vike-cli/src/cmd/node/setup.rs's CONTROL_FLAG_KEY).
Running setup again on a box that already has keys refuses rather than reissuing them:
$ vike-cli backend setup
OBSERVE_KEY and CONTROL_KEY already in .../settings/node.env, and `setup` will not silently
replace a key some client is signing with.
⚠ Re-run with --rotate to replace BOTH keys. Every client already holding the old ones — a
laptop's vike-cli, a vike-app --observe, a thin container — stops working the moment the daemon
restarts, and its symptom is an auth denial that reads like a revoked credential.
Nothing was written.Pass --rotate once you mean it:
vike-cli backend setup --rotateA rotation detaches every other client
--rotate replaces both keys and preserves every other line already in the store (crates/vike-cli/tests/node_cli.rs's rotate_replaces_both_keys_and_preserves_the_rest_of_the_store), but every client still holding the old pair fails its next handshake with an auth denial that reads like a revoked credential rather than like a rotation. Re-run backend connect on each of them afterward.
Every successful setup — first run or rotation — ends the same way, because the daemon reads both keys once at start and never re-reads them (crates/vike-cli/src/cmd/node/setup.rs's report):
sudo systemctl restart vike-tradehub # a systemd deployment
docker restart vike-tradehub # the containerconnect HOST — on the client's box
Raises an SSH tunnel to HOST (-N -f under the hood, so a taken port or an unreachable host fails synchronously rather than sitting there forwarding nothing), optionally takes the two keys, records the dial address, and finishes with a live round trip against the node.
On a first attachment, pipe both keys in:
printf '%s\n%s\n' "$OBSERVE" "$CONTROL" | vike-cli backend connect my-node --manualKeys never go on the command line
--manual reads two lines from stdin — observe, then control — and is the only way a key value reaches this command. A second positional after HOST is refused (crates/vike-cli/tests/node_cli.rs's a_key_never_goes_on_the_command_line): argv lands in shell history and in ps output for every other user on the box. A blank second line means observe-only — a client that can watch the node and place nothing.
Without --manual, connect writes nothing to the store: it raises the tunnel, records the dial address, and verifies with whatever keys this box already resolves (the process environment first, then the store). That is the ordinary second and later run:
vike-cli backend connect my-nodeA client already inside the trust boundary can skip the tunnel and dial the daemon directly:
vike-cli backend connect my-node --no-tunnelA successful run ends with the round trip (crates/vike-cli/src/cmd/node/connect.rs's verify):
verified: node my-node — LIVE — build 0.1.24
reached at 127.0.0.1:7879, 3 mount(s)
observe key id 4f2a…
⚠ compare those ids with the ones `vike-cli backend setup` printed on the daemon's box. They
match, or you are talking to a different node.A local key that disagrees with the incoming one is a refusal, not a silent switch
If this box already holds a different value for a key name than the one --manual was just given, connect refuses and prints both key ids rather than detaching whatever the old key reached (crates/vike-cli/src/cmd/node/connect.rs's replace_refusal). Pass --replace once you mean to point this client at a different node.
status — on the client's box
Reports the dial address, which keys resolved and from where, and whether the node answers right now — it prints the configuration half even when the round trip fails, so a bad address or a missing key is diagnosable from the same command that would otherwise just hang:
vike-cli backend statusdial address: 127.0.0.1:7879 (config.node_addr)
OBSERVE_KEY 4f2a… read plane, from the store
CONTROL_KEY 9b1c… write plane, from the process environment
⚠ a write key resolved here; whether the NODE admits orders is flags.tradehub_control on the
daemon's box, which this side cannot read.On a box that has never attached, it names exactly what is missing rather than printing an empty table or dialling nothing (crates/vike-cli/tests/node_cli.rs's status_on_an_unattached_box_names_what_is_missing):
$ vike-cli backend status
dial address: NONE — config.node_addr is unset, so every node verb still needs --node
OBSERVE_KEY absent read plane
CONTROL_KEY absent write plane
vike-cli backend: no config.node_addr on this box, so there is no node to ask. `vike-cli backend
connect <host>` records one; `--node HOST:PORT` still names one per command.disconnect — on the client's box
Closes the tunnel connect raised:
vike-cli backend disconnectIt matches the recorded forward spec, not a process id — ssh -f has already forked and exited by the time connect returns, so there is no child handle to hold onto (crates/vike-cli/src/cmd/node/connect.rs's run_disconnect). Running it with no recorded tunnel succeeds and says so, rather than failing on a state you already have:
no tunnel recorded by `vike-cli backend connect` on this box — nothing to close. (A tunnel
raised by hand is not recorded here; close it where you raised it.)--port N closes a forward on that port even when nothing was recorded for it (it still checks the recorded port first, then falls back to a plain -L N:localhost:N match with no host filter):
vike-cli backend disconnect --port 9200disconnect is not automated on Windows
pkill -f has no equivalent this workspace can reach without a Win32 call its lint policy forbids, so on Windows disconnect refuses and prints the exact command to run by hand instead:
Get-CimInstance Win32_Process -Filter "Name='ssh.exe'" |
Where-Object CommandLine -like '*7879:localhost:7879*' |
ForEach-Object { Stop-Process -Id $_.ProcessId }Flags
| Flag | Subcommand | Meaning |
|---|---|---|
--addr HOST:PORT | setup | Address the daemon binds (default 127.0.0.1:7879) |
--control | setup | Also set flags.tradehub_control = true, admitting order commands from a peer holding the control key |
--rotate | setup | Replace keys already in the store |
--port N | connect, disconnect | Node port to forward, dial, or close (default 7879) |
--manual | connect | Read both keys from stdin, one per line: observe, then control |
--no-tunnel | connect | This client is already inside the trust boundary — dial HOST directly, raise no forward |
--replace | connect | Overwrite a local key that differs from the incoming one |
-h, --help | all | Print usage |
The store
setup and connect --manual write into <project>/settings/node.env — the two node key names, kept apart from the much larger venue credential store so a reader of one need not open the other. Neither verb creates that file: an absent store is refused, naming the command that makes one (crates/vike-cli/src/cmd/node/mod.rs's open_store):
install -m600 /dev/null <project>/settings/node.envIf this box already has node keys under the old, shared credential file, they are still read from there — the refusal above is only about where the next write lands, not about losing keys that already exist.
$VIKE_SETTINGS_DIR names the settings directory outright, for a run against a project other than the one the working directory sits under.
Related
- secrets — the venue credential store
backend's writes are kept apart from. Its own missing-store refusal points atinstall -m600 /dev/null <path>, never atsecrets pathorsecrets template— those read a different file shaped for a different roster. - mcp — advertises no tool that can reach either of
backend's credential writers
secrets
Inspection of the one credential store — where it is, which key names it holds, which accounts those names resolve to, an empty grid to start one from — and the one narrow writer: set a single key, value from stdin or an environment variable, never from the command line.
Data
The hist store itself, and the key pair the server that fetches into it authenticates with.