| name | enclavia |
| description | Manage Enclavia confidential-compute enclaves (create, list, status, logs, stop/start/restart/destroy, push images, secrets, staged upgrades) via the `enclavia` CLI with `--json`; use when a task asks to deploy, inspect, or operate an Enclavia enclave from a terminal or agent. |
enclavia CLI (agent guide)
The enclavia binary manages enclaves over the Enclavia backend REST API.
With --json every command is fully scriptable, which is more
token-efficient than the MCP server at mcp.beta.enclavia.io for the same
operations.
The rule
- ALWAYS pass
--json (global flag, either position works).
- Parse stdout as a single JSON value.
- Branch on the EXIT CODE, not on prose:
- exit 0: stdout is the success object/array.
- exit non-zero: stdout is
{"error": "<message>", "kind": "<kind>"}
(kind is one of not_logged_in, unauthorized, error).
- Exception:
reproduce is a verification command (exit 0 = reproducible,
exit 2 = diverged, with the reproduce payload still on stdout). See its entry.
- stderr is human progress/diagnostics only; ignore it unless debugging.
Auth (do this first)
The CLI reads credentials from ~/.config/enclavia/credentials.json
(honours $XDG_CONFIG_HOME). The file holds an OAuth access token plus a
refresh token; the CLI auto-refreshes on expiry and rewrites the file, so
once it exists an agent keeps working with no further interaction.
enclavia auth login is INTERACTIVE: it opens a browser (OAuth 2.1 +
PKCE) and prints the approval URL to stderr. A human must approve the
login in a browser. When the browser and CLI run on different machines
(for example, the CLI runs over SSH or on a VPS), run the printed
ssh -N -L ... command on the browser machine, keep that tunnel open,
and then approve the printed URL. Once the credentials file exists, an
agent can keep using it without interaction. If no credentials exist,
commands fail with {"kind":"not_logged_in"}.
Set ENCLAVIA_BACKEND_URL (default https://api.beta.enclavia.io) to
target a non-prod backend, e.g. http://localhost:3000. Note the
credentials file also records the backend it was minted against and is
used as the base URL; keep them consistent.
Command reference (--json shapes)
Identifiers: <id> accepts a unique id prefix anywhere a full UUID works.
-
enclavia auth login --json
-> {"status":"logged_in","handle":<str|null>,"backend_url":<str>} (interactive; see Auth).
-
enclavia enclave list [--include-archived] --json
-> JSON ARRAY of enclave objects: {id,name,docker_image,status,instance_type,created_at,archived, ...}.
-
enclavia enclave status <id> --json
-> one enclave object: {id,name,status,status_detail?,mode,instance_type,docker_image,vsock_cid,endpoint?,created_at,pcrs?,error_message?}.
-
enclavia enclave logs <id> --json
-> {"build_log":<str|null>,"runtime_log":<str|null>}. build_log is the EIF build output (always available once building); runtime_log is the guest serial console, captured only for debug/QEMU enclaves (null on production Nitro). --json emits the raw object verbatim (pipe into a log viewer); without it the two logs print as labeled sections. Good first stop when status shows error or a build/boot failure.
-
enclavia enclave create [--instance-type small|medium|large] [--container-port N] [--storage-size-bytes N] [--name S] [--visibility private|public] [--production] [--upgradable] [--control-key NAME] [--anti-rollback] [--min-upgrade-delay DURATION] [--egress-allow HOST:PORT[/PROTO]]... [--egress-resolver IPV4]... [--egress-dns allowlist|open] [--egress-config PATH] --json
-> created enclave object {id,status,...}. Status starts waiting_for_image; next step is push. All flags below are immutable post-create.
--production: real EC2 Nitro hardware instead of the default debug/QEMU enclave. Requires an entitled account (paid plan or a saved payment method); otherwise the create is rejected.
--control-key NAME: self-hosted control-key custody for upgrades (implies --upgradable).
--anti-rollback: request synchronizer-backed anti-rollback protection for persistent storage. Only takes effect on a storage enclave (--storage-size-bytes) whose plan entitles it; otherwise the backend silently ignores it, so check synchronizer_enabled in enclave status --json to confirm what you got.
--min-upgrade-delay DURATION: minimum delay between confirming an upgrade and it taking effect (e.g. , , ). Requires .
Examples
Create, push, and poll until running:
enclavia enclave create --container-port 8080 --name api --json
# {"id":"<uuid>","status":"waiting_for_image",...}
enclavia push myapp:latest <uuid> --json
# {"image":".../<uuid>:latest","digest":"sha256:...","triggered":["<uuid>"],...}
# poll: read .status until "running", then read .endpoint
enclavia enclave status <uuid> --json
List enclaves:
enclavia enclave list --json # [{id,name,status,docker_image,...}, ...]
Rotate a secret, then apply it:
enclavia secret set <uuid> API_KEY=sk-... --json # {...,"restart_required":true}
enclavia enclave restart <uuid> --json # {"id":"<uuid>","status":"restart_requested"}