CLI
Install and use the krova CLI — authenticate, manage Cubes, SSH in, forward ports, and stream webhooks from your terminal.
krova is the official command-line interface for Krova Cloud. It talks to the same public REST API as the SDK, so anything you can do in the dashboard you can also do from your terminal: list and create Cubes, SSH in, forward a port to a service running inside a Cube, and verify webhook deliveries locally. It is open-source and published on npm as @krovacloud/cli.
Install
Install globally with npm (or pnpm / yarn / bun). This puts a krova command on your PATH. It's a pure Node.js CLI (requires Node.js 20 or newer) — no native binary and no extra toolchain to install.
npm install -g @krovacloud/cliVerify the install and check your version:
krova versionUpgrade the same way you installed — re-run npm install -g @krovacloud/cli to move to the latest release.
Authenticate
Every command runs against a context — a named bundle of an API key, a space, and (optionally) a base URL, stored in ~/.config/krova/config.json (written with owner-only 0600 permissions). There are two ways to create one.
Browser login (recommended)
krova login uses the OAuth 2.0 Device Authorization flow: it opens Krova Cloud in your browser, you approve a short code, and the CLI stores the resulting key — no copy-pasting secrets.
krova login
# On a headless machine, print the URL instead of opening a browser:
krova login --no-browserPaste an API key
If you already have an API key (created per space from Settings → API keys in the dashboard — see API keys), store it directly:
krova auth login --api-key kro_xxxxxxxx
# Check what's currently in effect and where it came from:
krova auth statusAn API key is scoped to a single space, so the CLI resolves your space automatically — you never have to paste a space ID.
Managing Cubes
The cubes command group covers the full lifecycle. The two most common read verbs also have top-level shortcuts, so krova list and krova get work without the cubes prefix (matching krova ssh).
krova list # list every Cube (alias: krova ls, krova cubes list)
krova get my-api # show one Cube by name or ID (krova cubes get)
krova cubes sleep my-api # pause compute billing (data is preserved)
krova cubes wake my-api # resume a sleeping Cube
krova cubes delete my-api # permanently delete a Cube
krova cubes ssh-port my-api --port 2222 # change the host port SSH is reachable onCubes can be referenced by name or ID anywhere a <cube> argument is expected.
Creating a Cube
--name, --image, and --ssh-key are required. The SSH key is your publickey — its contents are written to the Cube's authorized_keys at boot, so keep the matching private key handy (see SSH into a Cube below).
krova cubes create \
--name my-api \
--image ubuntu-24.04 \
--region us \
--ssh-key "$(cat ~/.ssh/id_ed25519.pub)" \
--vcpu 1 --ram 2 --disk 20Run krova images and krova regions to see the valid slugs. --vcpu, --ram (GB), and --disk (GB) default to 1, 1, and 10. Optional: --user-data (a cloud-init script) and --idempotency-key(a token that dedupes retried creates for 24 hours, so a network hiccup can't create two Cubes).
SSH into a Cube
krova ssh <cube>looks up the Cube's SSH host and port from the API and hands off to your system ssh. It uses your own SSH keys — the CLI never sees or transmits your private key.
krova ssh my-api # interactive shell
krova ssh my-api -- uptime # run one command and exit
krova ssh my-api -i ~/.ssh/my-key # pick a specific private key
krova ssh my-api -L 5432:localhost:5432 # forward a local port to a service in the Cube
krova ssh my-api -R 8080:localhost:80 # reverse-forward a port back to the CubeEverything after -- runs as a remote command instead of opening a shell. -L/-R are repeatable and map straight to ssh -L/-R — for example, forward Postgres out of a Cube with -L 5432:localhost:5432 and then connect a local client to localhost:5432 over the encrypted channel, without exposing the database publicly.
Host-key checking stays on. When Krova Cloudreturns a Cube's host keys, the CLI pins them and uses strict verification. Until then it falls back to normal SSH trust-on-first-use — you approve the fingerprint on the first connection, and it's remembered afterward.
"Permission denied (publickey)"
This is an SSH-key mismatch, not a CLI error: the Cube reached you fine, but the key you offered isn't in its authorized_keys. The Cube only accepts the public key you set when it was created. Fix it by pointing ssh at the matching private key:
krova ssh my-api -i ~/.ssh/the-key-you-created-it-with
# or load it into your agent once, then plain 'krova ssh my-api' works:
ssh-add ~/.ssh/the-key-you-created-it-withNote that plain ssh only auto-offers default key names (like ~/.ssh/id_ed25519). If your key has a custom name and isn't loaded into your agent, always pass -i.
Catalog
Inspect what's available to build with. These are read-only and don't require picking a Cube.
krova regions # regions with available capacity
krova images # OS image slugs you can pass to --image
krova pricing # per-resource hourly pricingDomains, snapshots & TCP mappings
Manage a Cube's attached resources. Each takes a Cube name or ID and supports --json.
# Custom domains
krova domains list my-api
krova domains add my-api --domain app.example.com --port 8080
krova domains rm my-api <domain-id>
# Snapshots + restore
krova snapshots list my-api
krova snapshots create my-api --name nightly
krova snapshots restore my-api <snapshot-id> # replaces the Cube's disk
krova snapshots rm my-api <snapshot-id>
# TCP port mappings (expose a Cube port on the host)
krova tcp list my-api
krova tcp add my-api --port 5432 --whitelist 203.0.113.4/32
krova tcp rm my-api <mapping-id>Contexts (multiple accounts & spaces)
Contexts work like kubectl / aws profiles: one per API key (and therefore per space). Switch between a personal space and a team space, or between prod and a test space, without re-authenticating each time. Both krova login and krova auth login create a context (named after your space by default, or pass --context <name>).
krova context list # all contexts (alias: krova ctx ls)
krova context current # the active one
krova context use team-prod # switch
krova context rename old new
krova context delete team-prod
krova whoami # current context, space, key, and base URLOverride the active context for a single command with --context <name>.
Webhooks
krova webhooks listenruns a local HTTP receiver that verifies each delivery's signature and pretty-prints the event — handy for developing against Krova Cloud webhooks without deploying.
krova webhooks listen --secret "$KROVA_WEBHOOK_SECRET"
# customize the bind address and path:
krova webhooks listen --addr 127.0.0.1:4666 --path /hooks --secret "$KROVA_WEBHOOK_SECRET"The signing secret can also come from the KROVA_WEBHOOK_SECRET environment variable. Deliveries with a bad or missing signature are rejected and reported, so you can trust every event you see.
Scripting & automation
Pass --json to any command to get machine-readable output instead of a table — pipe it into jq or a script.
krova list --json | jq -r '.[] | select(.state=="running") | .name'For CI and headless environments, configure the CLI entirely from the environment — no interactive login needed:
KROVA_API_KEY— the API key to use.KROVA_SPACE_ID— the default space (usually auto-resolved from the key).KROVA_CONTEXT— select a stored context by name.KROVA_BASE_URL— override the API base URL.KROVA_WEBHOOK_SECRET— default secret forwebhooks listen.
The equivalent per-command flags — --api-key, --space, --context, --base-url, --json, and --timeout (default 30s) — are global and work on every command. Precedence is flag → environment variable → stored context.
Troubleshooting
- Permission denied (publickey) — SSH key mismatch. See SSH into a Cube — pass
-iwith the key the Cube was created with. - "SSH info isn't available on this server yet" — your CLI is newer than the server. Nothing to do on your end; it resolves once Krova Cloud is on a current release.
- 401 / request rejected — the API key is missing, revoked, or scoped to a different space. Run
krova auth statusto see what's in effect, orkrova loginagain. - Command not found — run
krova <command> --help(or justkrova) to list the exact subcommands; not every group has alist(for example, webhooks only haslisten).
Next steps
- API keys — create and scope the key the CLI authenticates with.
- Cubes — sizing, sleep/wake, and how billing works.
- REST API reference — the same API the CLI is built on, for when you want raw HTTP or another language.
- Developer tools — the SDK, MCP server, webhook verifier, and n8n node.