keystonectl

The CLI documents itself, and that is the authoritative reference. Every command carries a description, runnable examples and the endpoint it calls, so the fastest way to learn it is to ask it:

keystonectl help              # every command, grouped
keystonectl help restart      # one command, with examples
keystonectl restart --help    # the same

keystonectl help <command> prints, among other things, the line Calls POST /v1/components/{name}:restart. — the mapping from CLI to API is in the tool, not only on this page.

Shell completion comes with it:

source <(keystonectl completion bash)   # or zsh, fish, powershell

The commands

Plan

CommandWhat it does
apply <plan.toml>Upload and apply a deployment plan
apply-dry <plan.toml>Validate a plan and log the reconcile it would run, changing nothing
graphShow the dependency graph and a valid start order
reconcileRepair the plan in effect
statusShow the applied plan, its status and its components
stop-planStop every component in the plan

Components

CommandWhat it does
componentsList components with state, PID and last health result
restart <component>Restart one component, cascading to its dependents
restart-dry <component>Show which components a restart would stop and start
stop <component>Stop one component

Recipes

CommandWhat it does
delete-recipe <name> <version>Remove a recipe from the agent’s store
recipesList the recipes stored in the agent
upload-recipe <recipe.toml>Add a recipe to the agent’s store

Agent

CommandWhat it does
healthCheck that the agent is alive, and for how long
versionShow this client’s version and commit

Local tools

CommandWhat it does
manifestCreate, sign and check dataset manifests
sha256 <file>Compute the SHA-256 of a local file
sign <file>Sign a file, producing a detached .sig
verify <file>Verify a detached signature the way the agent will

Global flags

These apply to every command.

FlagWhat it isDefault
--addrAgent base URL, resolved on the SSH host when –ssh is used (or KEYSTONE_ADDR)http://127.0.0.1:8080
--sshReach the agent through SSH: [user@]host[:port] (or KEYSTONE_SSH)(none)
--tokenBearer token for the agent API (or KEYSTONE_API_TOKEN)(none)

A flag always wins over its environment variable, which wins over the default.

--addr is worth exporting when the agent does not use the default port:

export KEYSTONE_ADDR=http://127.0.0.1:9180
keystonectl components

restart takes --wait pid|health and --timeout, so a script can block until the component is actually serving:

keystonectl restart api --wait health --timeout 120s

Exit codes

CodeMeaning
0The request succeeded
1The agent or the network reported a failure
2The command was used wrongly — bad arguments, bad --ssh destination

Note stop-plan (everything) versus stop <component> (one thing) — they are different commands, and the plural mistake is an outage.

Every command prints the agent’s own response. restart-dry reports the order it would use, not a bare OK:

$ keystonectl restart-dry api
{
  "startOrder": [
    "api"
  ],
  "stopOrder": null
}

Reaching an agent bound to loopback

The agent listens on 127.0.0.1 by default, and binding anything else requires a token. On a real device that means its API is only reachable from the device itself.

--ssh carries the request there, so there is no ssh -L to keep alive in another terminal and no port to expose:

keystonectl --ssh ops@edge-001 components
keystonectl --ssh ops@edge-001:52022 --addr http://127.0.0.1:9180 restart-dry api

--addr is resolved on the far side. The default http://127.0.0.1:8080 is therefore the agent’s loopback — exactly the interface it is bound to. Both variables can be exported together for a device you work on often:

export KEYSTONE_SSH=ops@edge-001:52022
export KEYSTONE_ADDR=http://127.0.0.1:9180
keystonectl status

What it does under the hood is run your own ssh client with -W, which splices its stdio to a host and port on the far side. That is deliberate: it inherits your ~/.ssh/config — Host aliases, IdentityFile, ProxyJump through a bastion, the agent, certificates and known_hosts — and the host key is verified by ssh under your own rules. Keystone adds no cryptography of its own here.

The consequences are worth knowing:

  • It needs the ssh binary on your machine (the device only needs sshd).
  • The device’s sshd must allow AllowTcpForwarding, which is the default but is sometimes turned off on a hardened image. If it is off, -W fails.
  • SSH errors — unknown host, rejected key — reach you verbatim on stderr rather than as an opaque connection failure.
  • --ssh is Unix-only. On Windows the rest of the CLI works; forward the port with ssh -L and point --addr at it.