ekka CLI reference¶
The ekka CLI is your command line for running and governing agents on EKKA.
Every command takes --help, and -v adds the mechanism behind any output:
the hash chain, the ids, the internal names. The default view says what
happened.
Setup and identity¶
| Command | What it does |
|---|---|
ekka login --email [email protected] |
Sign in. We email a link; there is no password. Creates your account the first time. |
ekka login [--email <you>] [--no-browser] |
Sign in via the browser and store a fresh session token. --email sends a one-time sign-in link instead; --no-browser prints the URL. |
ekka whoami [--json] |
Show the org, environment and Enclave identity you're signed in as. |
ekka logout |
Clear local session tokens (keeps profile metadata, the vault, and the Enclave identity). |
ekka doctor |
Check whether an agent can work here and name what is missing. Runs eight checks in the order a new organization has to satisfy them, and always prints all eight. |
Signing in, and enrolling the machine, are two different things
ekka login refreshes your session and leaves the Enclave alone. Enrolling
this machine is ekka enclave create then ekka enclave start <id>, which
you do once per machine. After that, login is all you need when your
session expires.
Enclave¶
| Command | What it does |
|---|---|
ekka enclave list |
Every Enclave your organization has, its health, and which build each one is running. Run this before creating one: you may already have an Enclave waiting to be claimed. Revoked ones are hidden unless you pass --all. |
ekka enclave create --name my-laptop |
Create an Enclave id. Give it a name you will recognize in the list, not a placeholder. The id is safe to share with whoever runs the machine. |
ekka enclave start |
Boot your Enclave in the foreground. Wait for authenticated; entering run loop. The first time, ekka enclave start <id> claims it for this machine, and that first run also looks for Claude Code (see below). On a server, run it under systemd instead of leaving it in a terminal: see Running on a server. |
ekka enclave install-service [--dry-run] [--no-start] |
Install the Enclave as a systemd service so it survives reboots. The unit is generated from this machine: the enrolled home, the account that owns it, and the path of this binary. Linux, and needs root. See Running on a server. |
ekka enclave status [--json] |
Whether an Enclave is running on this machine, and which build. Local only, and it uses no network. For a machine you are not sitting at, use ekka enclave list. |
ekka enclave stop |
Stop the Enclave process on this machine. The organization's record is untouched, so you can start it again. |
ekka enclave pause <id> |
Stop giving this Enclave work. Anything already running finishes first. |
ekka enclave resume <id> |
Start giving a paused Enclave work again. |
ekka enclave revoke <id> |
Revoke an Enclave permanently and release its slot. This is how you clean up one you created by mistake. |
ekka enclave reset |
Erase this machine's enrollment so it can enroll again. Local and offline. |
ekka enclave custody [keychain\|file] |
Where this machine keeps its vault unlock key. With no mode it only reads. Moving it changes nothing else: the key is the same and no stored data is touched. Choose file on a server or CI runner, where nobody can answer a keychain prompt. |
The Enclave is where each governed operation actually runs, on your side.
Your data and keys never leave your machine. The Enclave is built into the signed
ekka binary, so ekka enclave start is all you need.
Claude Code on this machine¶
When you claim an Enclave, that first ekka enclave start <id> checks whether
Claude Code is installed here. If it is, the path is recorded as
EKKA_AI_CLI_CLAUDE in ~/.ekka/enclave.env and your Enclave reports that it
can offer that model, the same way it reports any other gate. The message names
the path it found and the file it wrote it to, because a value you did not type
should always trace back to a sentence you read.
It happens once, at claim. It records a path and nothing else about your machine, and it sends nothing anywhere.
Being available is not permission. Nothing runs through the model until you grant it to a plan, which is the same rule that governs every gate.
The setting is optional. To turn it off, delete the EKKA_AI_CLI_CLAUDE line
from ~/.ekka/enclave.env and restart the Enclave: with the key unset, the
Enclave offers no Claude gate. ekka enclave config prints the effective value
and whether it came from the file, the environment, or a default.
revoke and reset are not interchangeable¶
ekka enclave revoke <id> |
ekka enclave reset |
|
|---|---|---|
| Acts on | your organization's record of the Enclave | this one machine |
| Needs the network | yes, and works from any machine | no, it is offline |
Removes the row from enclave list |
yes | no |
| Destroys local secrets | no | yes: the vault, the sealed identity and the device secret in this machine's keychain |
Revoking stops the Enclave receiving work within about 90 seconds, lets a step
already in flight finish, keeps every receipt it produced, and releases its
Enclave slot. Any member of the organization can run it, and it asks you to
confirm by typing the Enclave's name; --confirm <name> skips the prompt in a
script.
Use reset on a machine whose vault is damaged, or on hardware you are handing
on. What it erases exists nowhere else.
Guided demo¶
| Command | What it does |
|---|---|
ekka demo |
Watch EKKA govern one real call, end to end. It creates a plan in your organization, denies a call it has no permission for, grants that permission, runs it again, and verifies the receipts. The plan is left behind so you can read what happened. |
ekka demo takes no arguments. See the Build a governed AI application for a
beat-by-beat walkthrough.
Gate operations¶
Run one governed gate operation on the real governed path, or preview the decision without executing it. Admin-only (EKKA enforces this on your own tenant).
| Command | What it does |
|---|---|
ekka gate <type> <op> --instance <alias> --resource <name> [--input <json>] [--check] |
Run one governed gate operation. --check previews allow or deny with no I/O and no cost; without it, the op executes through the gate and records a signed receipt. Types include postgres, llm, and mcp. |
ekka gate register <url> [--alias <name>] |
Register a gate your organization runs, at the address this machine uses to reach it. The Enclave hands EKKA the gate's own signed declaration, and EKKA never connects to the gate, so it may listen on 127.0.0.1 or inside your network. |
ekka gate revoke <gate> [--reason <text>] |
Stop using a gate your organization registered. It is marked revoked, not deleted, so the record of who registered it and when stays readable. |
ekka gate hide <ref> / unhide <ref> / hidden |
Take something out of your organization's lists, put it back, or see what is hidden. Hiding changes lists only: a hidden gate still runs and its grants still cover it. |
--instance names which gate instance serves the call. Every gate type has one,
including llm, and there is no default, so the command always names the gate
you meant. Run ekka gate list to see the instances your organization has: it
prints them as <type>/<instance>.
# A database read (execute): reports ALLOWED + a receipt, or DENIED before any I/O
ekka gate postgres list --instance demoV1 --resource customers
# Preview only: does a standing Grant cover this? (no I/O)
ekka gate postgres list --instance demoV1 --resource customers --check
# An AI-model call: the model is the resource, the prompt rides in --input
ekka gate llm infer --instance prod --resource anthropic/sonnet-4 \
--input '{"prompt":"hello"}'
Execute mode needs a running Enclave (ekka enclave start).
Naming a gate instance, and its credentials¶
A plan refers to a gate instance by alias, so the plan never carries a connection string. Credentials are deposited against the gate and their values are never printed back.
| Command | What it does |
|---|---|
ekka gate alias create <gate> <alias> ... |
Name one gate instance so plans can refer to it. |
ekka gate alias list <gate> |
The aliases defined on one gate. |
ekka gate alias revoke <gate> <alias> |
Revoke one alias. Plans naming it stop resolving. |
ekka gate credential deposit <gate> ... |
Store a secret for a gate to authenticate with. |
ekka gate credential list <gate> |
The credential refs one gate holds. Values are never printed. |
ekka gate credential revoke <gate> <ref> |
Revoke one credential. |
Grants¶
A Grant is durable authorization: an agent may perform an operation on a resource, through a gate, until you revoke it. Admin-only.
| Command | What it does |
|---|---|
ekka gate grant add --type <type> --instance <alias> --resource <name> --capability <code> [--agent <id>] [--ttl <seconds>] |
Grant an agent one capability on one resource. Capability codes are listed on Pricing. --instance names the gate that serves the grant, for every gate type including llm, and there is no default. --agent is optional: omit it and ekka resolves your organization's core agent (pass it only to target a specific agent on a multi-agent team). --ttl is in seconds with no suffix, and defaults to 30 days. For --type llm, add per-call caps: --max-input <n> --max-output <n> --max-total <n>. For an apis/desks grant, --constraint <file> sets the limits the desk backend's adapter enforces: a JSON file, checked on your computer before anything is sent, where an unknown key is refused. |
ekka gate grant list [--agent <id>] [--json] |
List active Grants (optionally for one agent). |
ekka gate grant revoke <grant-id> |
Revoke a Grant. The same operation is refused again, live. |
ekka agent declare <agent-code> --add <capability> |
Widen what an agent asks for. A grant may only name a capability the agent already declares, so this comes first. Creating a plan widens the declaration automatically while you own the agent and have never published it, which is why you rarely need this by hand. |
ekka agent list [--json] |
Agents that can act here: your own, your core one, and any you installed. |
ekka agent create <name> |
Create a new agent in your organization. |
ekka agent catalog [--json] |
Published agents you could install, and where you stand with each. |
ekka agent install <agent> |
Let a published agent act here. Installing consents to the permissions it asks for. |
ekka agent approve <agent> |
Re-consent after its publisher changed what it asks for. Until you do, it keeps running under what you already agreed to. |
ekka agent uninstall <agent> |
Stop an agent acting here. Your grants for it are kept, so re-installing does not mean re-granting. |
ekka agent publish <agent> |
Offer one of your agents to every organization on this EKKA. Asking is not publishing: the agent stays private to your organization until EKKA reviews it, and nothing about it changes in the meantime. An agent carries the permissions it asks for, and installing it consents to them, so a person reads it before it reaches anyone else. Refused for your core agent (the identity your own plans run as) and for an agent that declares nothing, since there would be nothing to consent to. |
ekka agent show <agent-code> |
What one agent declares, and which plans use each item. DECLARED: nothing is normal on a new organization: create a plan and it fills in. |
ekka agent unpublish <agent> |
Stop offering a published agent to other organizations. The agent stays, and plans that run as it keep running. Refused while another organization has it installed. |
ekka agent data validate <file> |
Check an agent's data declaration (the tables it keeps) before you publish it, including whether an Enclave could build every table. Needs no sign-in. |
ekka agent data set <agent> <file> |
Say what one of your agents keeps. Before the agent is published you may change it freely; afterwards, a change that would lose records somebody holds is refused and names them. --none says it keeps nothing. |
ekka agent settings set <agent> <file> |
Say what your agent asks an installing organization for, such as which channel to post to. Safe to change at any time. --none says it asks for nothing. |
ekka agent settings values <agent> [--set key=value ...] |
What your organization has answered for an agent you installed, and what it still owes. --set answers a field and repeats. |
# Let your agent read the customers table (agent resolved automatically)
ekka gate grant add --type postgres --instance demoV1 \
--resource customers --capability knowledge.postgres.read
# Let your agent call a model, with per-call token caps
ekka gate grant add --type llm --instance prod \
--resource anthropic/sonnet-4 --capability llm.infer \
--max-input 4000 --max-output 1000 --max-total 5000
Policies¶
A policy is one rule your organization writes down, checked before a plan
runs, before a permission is issued, and before a plan is created. A rule starts
advisory: checked and recorded, nothing stopped. --binding is what lets it
refuse. Full walkthrough: Policies. The principles these derive
from are your Charter.
| Command | What it does |
|---|---|
ekka policy types |
Every kind of rule EKKA can check, and the field names each one takes. Read this before writing a policy. |
ekka policy draft <name> --type <type@version> --field <k=v> |
Write or edit a draft. A draft enforces nothing. Repeat --field per value; amounts carry their unit, like --field ceiling_micro_usd=5USD. --file <f.json> reads the values from a file instead. |
ekka policy draft ... --outcome <refuse\|determine\|notify> |
What happens when the rule is broken. Defaults to refuse, which only stops anything with --binding. |
ekka policy draft ... --binding |
Let the rule actually stop things. Without it the rule records every firing and lets the work through, which is how you see what it would have refused. |
ekka policy publish <name> |
Put the draft in force. It freezes here: changing it drafts the next version and the old one stays readable. |
ekka policy list |
The rules this organization has written. The WHEN BROKEN column says records only or refuses, which is not the same as active. --all includes rules no longer enforced. |
ekka policy show <name> |
One rule in full: its values, its state, and its fingerprint. |
ekka policy disable <name> |
Stop enforcing a rule, keeping it readable. Never a delete: a past refusal names it. |
Plans and schedules¶
A plan wires governed gate operations into ordered steps; a schedule runs a plan on a cadence for your organization only. See Create your first plan for authoring. Scheduling needs an admin role, and a plan must be active to be scheduled.
| Command | What it does |
|---|---|
ekka plan list [--all] [--requested] [--limit <n>] |
The plans you can use: yours, and the ones your organization has adopted. --all also shows colleagues' unlisted plans and who wrote each one, so you can read a plan and ask them to publish it. --requested is the queue waiting for an administrator, with who offered each one and how long it has waited. |
ekka plan show <plan> |
One plan: its steps, the capability each step consumes, and the inputs it takes at run time. When the plan has a review step (a model answers the author's rubric as JSON, and the plan branches on a word from the author's list), a quality section shows what that step reported over the last graded runs: the latest word or score, the direction it moved, and how many runs graded it. The text the review judged never leaves your Enclave; only the author's bounded fields are shown. |
ekka plan show <plan> --definition |
The plan as authored: what your file said. |
ekka plan show <plan> --verify |
Recompute the plan's fingerprint and say whether it still matches what was recorded when the version was created. |
ekka plan show <plan> --compiled |
The plan that runs, after skills and cataloged calls are expanded and every @input.x is compiled into a typed binding. |
ekka plan template <file.json> --gate <type>[/<instance>] --op <read\|write\|list\|infer\|invoke> |
Write a complete starter plan for one governed gate call, so your first plan is not a blank file. The file carries the plan's name beside its steps, so plan create needs nothing else. Add --resource <id> to say which thing inside the gate: a model for llm (anthropic/sonnet-4), a recipe for process (recipes/nightly-report). Refuses to overwrite an existing file. |
ekka plan validate <file.json> [--json] |
Check a plan file the way plan create would, creating nothing. Prints what the plan would need: each capability and resource, and whether a grant already covers it. Exits 0 only when create would succeed, so CI can hold plan files to the same bar. |
ekka plan create <file.json> [--schedule <cadence>] |
Create the plan the file describes and print its versioned identity (for example [email protected]). EKKA assigns the version number and says which digit moved and why. The file carries the plan's name and steps; it must not carry a version, a status or an input schema, and naming one is refused. The new version lands unlisted: yours alone until you offer it. On success it prints what the plan needs, with the exact ekka gate grant add command for anything missing. Add --schedule (for example --schedule "@daily") to create and schedule in one command. |
ekka plan delete <plan> |
Delete a plan. It stops running and leaves ekka plan list, and the identity can be used again. Runs it already produced keep their Receipts, and ekka receipts verify still verifies them, because each run carries its own copy of the plan. A run already in flight finishes normally. Refused while a schedule still points at the plan: ekka plan unschedule first. |
ekka plan hide <plan> / unhide <plan> / hidden |
Take a plan out of your organization's lists, put it back, or see what is hidden. A hidden plan still runs. To stop a plan being used, revoke its grant or delete it. |
ekka plan run <plan-identity> [--input key=value ...] |
Run a plan once, now, as a governed run. Pass the full identity that plan create printed. --input repeats. |
ekka plan schedule <plan-identity> --cron "<expr>" [--tz <zone>] [--input key=value ...] |
Run a plan on a cadence. Standard 5-field cron (for example "0 9 * * 1-5") or an alias (@hourly, @daily, @weekly, @monthly). --tz is an IANA timezone (default UTC). Inputs are the same surface as ekka plan run and ride on every fire. |
ekka plan schedule <plan-identity> --every <interval> |
The friendly interval form: 1m, 5m, 15m, 30m, 1h, 6h, 12h, or 1d. |
ekka plan schedules [--json] |
List your schedules: the pinned plan version, cron, active state, NEXT-RUN, LAST-RUN and the schedule id. A populated LAST-RUN means the schedule is firing, and a row pinned behind a newer version says so, with the repoint command beside it. |
ekka plan repoint <schedule-id> --to <plan-identity> |
Point a schedule at a different version of the same plan. A schedule keeps running the version you pinned even after you create a newer one, and ekka plan schedules says when that has happened; this is how you move it, deliberately. |
ekka plan unschedule <schedule-id> [--pause\|--resume] |
Remove a schedule, or pause and resume it in place. |
Offering a plan to your organization¶
A plan you create is yours. It stays out of everyone else's list, nobody else can run it, and it will never fire on somebody else's schedule. That is the point: writing a plan is not the same decision as adopting one.
| Command | What it does |
|---|---|
ekka plan publish <plan-identity> |
Offer a plan to your organization. This asks, and publishes nothing. An administrator accepts or declines it. While it waits, the plan stays unlisted and only you can run it. |
ekka plan approve <plan-identity> |
Accept a plan somebody offered. Everyone in the organization can then run it, on the organization's permissions. |
ekka plan decline <plan-identity> --reason <text> |
Refuse a plan, and say why. The reason is required, because the author reads it and a refusal they cannot act on is a dead end. They can fix the plan and ask again. |
publish asks. It does not publish.
The success line says requested, never published, and it names the exact command whoever must answer will run. Asking twice is refused rather than queued: one thing waiting on one decision.
# Every weekday at 9am, New York time, with an input
ekka plan schedule "[email protected]" \
--cron "0 9 * * 1-5" --tz America/New_York \
--input audience=sales
# The common case: just run it hourly
ekka plan schedule "[email protected]" --every 1h
Every scheduled fire is a normal governed run: Grants are enforced, every step
produces a signed Receipt, and ekka receipts verify covers scheduled runs
exactly like manual ones. Pausing keeps the schedule; resuming realigns it to
the next real slot, and a paused schedule never back-fires missed runs. Missed
fires during downtime are skipped, not bursted.
--definition and --compiled answer different questions
They are two different documents. A cataloged API step is written as
{call, to, subject, text} and reaches the gate as
{resource, key, value: {method, body}}. Only the compiled form answers
"why did my run do that", because it is the one that actually ran.
A compiled plan appears once the plan is created. Editing a plan clears it
until it is recompiled, and --compiled says so rather than printing
nothing.
Receipts and runs¶
| Command | What it does |
|---|---|
ekka receipts list [--json] |
List recent runs found in your local audit log (newest first). |
ekka receipts show <run-id> [--json] |
Print a run's receipt chain (the Gate Token issued, each gate's signed receipt, the run attestation) with its hash links. The run attestation is hash-linked, not signed: see Receipts. |
ekka receipts verify [--json] |
Verify the whole local receipt chain offline: recompute every hash link and re-check the signature on every local operation receipt. Takes no run id; for one run use ekka receipts show <run-id>. |
ekka run list [--limit N] [--json] |
List recent runs, newest first. |
ekka run show <run-id> [--json] |
Show EKKA's allow or deny decision for a run, including the reason an action was denied and which grant would have covered it. A run whose review step reported grades shows them, one line per graded operation. |
ekka receipts trace <run-id> |
The unsigned half of a run: which endpoint each step reached, its status and how long it took. Troubleshooting detail, never evidence. The signed half is receipts show. |
ekka audit findings [--idle-days <n>] [--deny-threshold <n>] |
Grants nobody has used, and agents collecting refusals, each with a recommendation: revoke, shorten or review. Read from your organization's own audit chain. |
A denied action produces a decision but no receipt chain (nothing ran, so
nothing was signed): use ekka run show for those. See
Governance receipts for how to read them.
Skills¶
Reusable bodies of work a plan can call by name. See Skills for what they are and how to write one.
| Command | What it does |
|---|---|
ekka skill list [--all] [--requested] [--archived] [--json] |
The skills you can use: yours, and the ones your organization has adopted. --all also shows colleagues' unlisted skills and who wrote each one. --requested is the queue waiting for an administrator. --archived includes withdrawn versions. |
ekka skill show <name>[@<version>] [-v] [--json] |
One skill: what it takes in, what it hands back, its size and its versions. Without @<version> you get the newest. |
ekka skill validate <file> [--json] |
Run every check create makes and create nothing. Use it while you are writing the file. |
ekka skill create <file> [--json] |
Create a version from a skill file. EKKA assigns the version number; a version is never rewritten. It lands unlisted: yours alone until you offer it. |
ekka skill publish <name>@<version> |
Offer a skill to your organization, so anyone here can build plans on it. This asks; an administrator decides. |
ekka skill approve <name>@<version> |
Accept a skill somebody offered. Everyone here can then build on it. |
ekka skill decline <name>@<version> --reason <text> |
Refuse a skill, and say why. The author reads the reason and can fix it and ask again. |
ekka skill fork <name>[@<version>] [--out <file>] |
Copy a published skill into a file you can edit. Only an open skill can be copied. |
ekka skill promote <plan-file> --name <name> [--op <id>] [--out <file>] |
Turn an operation from a plan file into a skill file. Every @input.<name> becomes a port. |
ekka skill from-api <api>[@<version>] --call <call> [--name <name>] [--out <file>] |
Write a skill file for one operation of a cataloged API. |
ekka skill archive <name>@<version> [--json] |
Stop offering a version. It leaves the listing and the next plan naming it is refused. Plans that already use it keep working. |
ekka skill unarchive <name>@<version> [--json] |
Offer an archived version again. |
Archiving does not stop anything that already runs
A plan copies a skill's steps into itself when the plan is created, so it
never looks the skill up again at run time. A schedule firing tonight runs
exactly what it ran last night. Archiving changes the future: the skill
leaves ekka skill list, and the next plan that names it is refused.
A version is always required, because [email protected] and [email protected] are
different bodies and a plan pins one of them. Nothing is deleted, and
unarchive undoes it.
promote, from-api and fork create nothing
All three write a file on your machine. Read it, edit it, then
ekka skill validate and ekka skill create. A generated body has a blank
output_map for you to fill in, so creating it unread would ship a
contract nobody chose.
create makes a version. publish offers it to other people.
They are two commands because they are two decisions. ekka skill create
freezes a version that only you can build on. ekka skill publish
puts it in front of an administrator, who accepts or declines it with a
reason. Nothing you write reaches your colleagues until somebody agrees.
ekka skill publish takes a name and version, not a file. Passing a
file path is refused, and the refusal tells you to run ekka skill create.
APIs and the catalog¶
Third-party APIs a plan can call: Slack, S3, Gmail, and whatever your organization catalogs itself. See Add your own API for the whole flow.
A connection is per machine. The credential lives in this machine's vault and never leaves it, so an API connected on your laptop is not connected on a colleague's.
| Command | What it does |
|---|---|
ekka api list [--json] |
What this organization can connect, whose row each one is, and which are connected on this machine. |
ekka api describe <name> [--version <x.y.z>] |
What the API is, in plain English: its address, the credential it takes, and every call it offers. Name a version to read one that is no longer the newest. |
ekka api spec <name> [--version <x.y.z>] [--json] |
The same facts as the fields a plan step carries. This is what you copy when writing a plan against it. |
ekka api connect <name> |
Connect it on this machine. Asks for what the API needs and stores the credential in this machine's vault. |
ekka api test <name> [--connection <name>] [-v] |
Does this connection work right now: four answers on one screen, for the connection file, the credential in this machine's vault, the grant, and a live call. A check that cannot be performed says so and is never reported as a pass. Add --connection when this machine holds several connections of the same API. |
ekka api disconnect <name> [--yes] |
Remove the connection and its credential from this machine. The catalog row is untouched. |
Putting an API into the catalog¶
Your own internal APIs are yours to add, with no deploy and no waiting on us. A
row you add is private to your organization and named <your-org>/<name>.
| Command | What it does |
|---|---|
ekka api catalog validate <file.json> [--json] |
Check a catalog file and create nothing. EKKA runs the real insert against the real rules and throws it away, so the answer is the one adding it would give. |
ekka api create <file.json> [--json] |
Create a version of the API in this file. The file does not carry a version; EKKA works the number out from what changed, and prints the reason. |
ekka api publish <org>/<name>@<version> [--json] |
Offer one of your rows to every organization on this EKKA. It stays private until EKKA approves it. |
ekka api catalog archive <org>/<name>@<version> [--json] |
Stop offering one of your rows. It leaves ekka api list and the bare name stops resolving to it. |
ekka api catalog unarchive <org>/<name>@<version> [--json] |
Offer an archived row again. |
A row is never edited, and archiving is how you retire a wrong one
Fixing an API means publishing the next version, because a plan pinned to version 1 must keep running exactly what it ran yesterday. That leaves the wrong version still in the menu, and archiving is what takes it out.
Nothing connected to it breaks: a connection pins a version and a compiled
plan holds the whole request, so neither reads the row again. An archived row
is still readable by naming its version
(ekka api describe <name> --version 1.0.0), which is how you see what an old
connection points at.
Programs a plan may run¶
A recipe is one program on this machine, with a fixed argument list and named parameters that each declare what they accept. A plan names a recipe. It cannot name a program and it cannot write a command. See Run a program from a plan.
| Command | What it does |
|---|---|
ekka process recipe validate <file.json> |
Apply every rule add applies and register nothing. Prints what would be registered, the arguments in order, and the fingerprint a real registration would produce. |
ekka process recipe add <file.json> |
Register the recipe in this file, so a plan may name it. The file carries the recipe's name, so the same file registers the same recipe from your laptop or from CI. Registering permits nothing: it prints the grant to run next. |
ekka process recipe list |
The recipes registered on this machine. |
ekka process recipe show <name> |
One recipe in full: the program, every fixed argument, what each parameter accepts, the limits a run is held to, and whether the program is pinned by its contents. Read this before granting. |
ekka process recipe remove <name> [--yes] |
Remove a recipe, so nothing can invoke it. Grants naming it stop working. |
ekka process test <name> [--param k=v ...] |
Resolve the recipe with real values and print the program and every argument, one per line. Starts nothing. --param repeats. |
# What exactly would run, before anyone is allowed to run it
ekka process recipe show disk-report
ekka process test disk-report --param mount=/
# Then a separate decision: let an agent invoke it
ekka gate grant add --type process --instance <the process gate> \
--resource recipes/disk-report --capability process.invoke \
--no-fingerprint
A value that fails its parameter's restriction is refused, and the refusal does not print the value, because a parameter can carry a credential. One parameter is one argument: a value with spaces in it cannot become two.
Desks¶
A desk is a workspace NVIDIA OpenShell isolates on your own machine, where one agent does one approved job. See Agent desks.
Every change to a desk is a governed plan run, recorded with a receipt. The
command runs the plan through the Enclave on your computer and prints the run
and its receipt. Commands marked as you read the desk backend under your own
sign-in (ekka desk login), which only reads. People and keys are set on the
desk backend's machine, at install.
| Command | What it does |
|---|---|
ekka desk login / ekka desk logout |
Sign in to the desk backend in your browser, or remove that sign-in from this computer. |
ekka desk backend show / ekka desk backend set |
Where this computer's desk commands go, and how you sign in there. |
ekka desk profile list / show <name> |
The kinds of connection the desk backend knows: which hosts a key reaches, and which programs may use it. As you. |
ekka desk connect |
Lists the kinds of connection the desk backend knows, and names the step that sets a key on the desk backend's machine: sudo ./up.sh connect <provider>. Naming one, ekka desk connect <provider>, refuses with that step. As you. |
ekka desk connections |
The keys the desks may use, and which desks use each. Never a key's value. As you. |
ekka desk disconnect <name> |
Detach a connection from every desk that uses it, one governed plan run per desk. The connection itself is removed on the desk backend's machine. |
ekka desk create <name> --provider <profile> ... |
Make a desk with the connections it may use, as a governed plan run. --provider repeats. The image is named by digest. A desk starts empty: code reaches it through its setup plan, and a create that names a repository is refused. |
ekka desk stop <name> / start <name> / delete <name> |
Pause a desk, bring it back, or delete it with its work folder, each as a governed plan run. |
ekka desk status <name> |
A desk's state on the desk backend, as a governed read. While a change is still running it says so and names the change's operation. A change whose outcome was not known is checked again here. Changes nothing on the desk. |
ekka desk locks |
Which desks are held, by a job or by a change, read from the Enclave on your computer. For a change whose outcome is unknown it names the next two steps: ekka desk status, then ekka desk release. Changes nothing. |
ekka desk release <name> --operation <id> |
Release a desk held by a change whose outcome is unknown, after reading the desk with ekka desk status. EKKA refuses it while the change is still running; it works only after the change has settled. Asks you to type the desk's name. Changes nothing on the desk. |
ekka desk logs <name> |
A desk's recent log lines. As you. |
ekka desk policy show <name> |
What a desk may reach, in plain words. Changes nothing. As you. |
ekka desk policy check <file> |
Check a policy file before using it. Changes nothing. |
ekka desk policy set <name> <file> |
Replace a desk's policy, as a governed plan run. Shows both side by side and asks first. |
ekka desk allow <name> --program <path> --host <host> / deny ... |
Let one program in a desk reach one host, or stop it, as a governed plan run. |
ekka desk access list |
Who may use the desks. People are added on the desk backend's machine with sudo ./up.sh invite <user>, and removed with sudo ./up.sh revoke <user>. As you. |
ekka desk list / ekka desk show <name> |
The desks this Enclave runs work on, and one desk in full: its pins and the exact Grant it needs. |
ekka desk repin <name> |
Approve a desk that was changed or made again under the same name. Work on it waits for this approval. |
ekka desk add <file.json> |
Register a desk that already exists on the desk backend and was not made with ekka desk create. |
# A desk for one agent's job, then the Grant that lets the agent work on it
ekka desk create code-desk --provider claude-code --provider github
ekka desk show code-desk
Webhooks and events¶
A webhook is one sender of events, such as a New Relic account. A plan bound to it starts when the sender reports something the plan listens for. See Start a plan when something happens.
| Command | What it does |
|---|---|
ekka webhook add <name> --provider <sender> --type <event-type> |
Register a webhook. For New Relic, EKKA sets up the sender's side from your Enclave and nobody sees the key. For another sender, --show-key shows the key once, or --key-file <path> writes it to a new file only you can read. --type repeats. |
ekka webhook configure <name> --bind <plan[@version]> |
Start a plan when this webhook sends an event the plan listens for. --unbind <plan> stops it. --allow and --disallow change the event types it may send; --yes confirms starting the plans EKKA names for a newly allowed type. |
ekka webhook enable <name> |
Make a configured webhook live. For New Relic, --issues-filter <file> or --all-issues says which issues it sends. |
ekka webhook list / show <name> |
This organization's webhooks, and one in full: its state, its key's age, and what it accepted and refused. |
ekka webhook pause <name> / resume <name> |
Stop a live webhook taking events, or take them again and start what it held. |
ekka webhook rotate-key <name> |
Change its key. The old key keeps working for 24 hours, or stops at once with --revoke-old. |
ekka webhook delete <name> [--confirm <name>] |
Delete a webhook and what EKKA set up at its sender. Waiting deliveries are canceled; runs already started continue. |
ekka events list |
Events EKKA accepted, newest first. A refused request is not an event: see ekka audit list --type event.refused. |
ekka events show <event> |
One event and everything it led to: each plan, its outcome, and its run. |
ekka events cancel <event> |
Cancel an event's waiting deliveries. A run already started is never stopped. |
ekka events send <webhook> --type <event-type> |
Send one real event by hand through a webhook. Plans bound to it can start real runs. --file sends a prepared event document. |
ekka events register <name> --contract <file> |
Register an event type, or its next version, from a contract file. |
Decisions¶
A plan can stop and ask a person. The plan names a role; your organization decides who holds it. See Ask a person before the agent acts.
| Command | What it does |
|---|---|
ekka decide list |
The decisions waiting on you. |
ekka decide show <id> |
One decision in full before you answer: the question, the answers on offer, when it runs out, and what earlier steps found. |
ekka decide answer <id> <choice> [--note <text>] |
Answer it. The first valid answer counts, and is recorded against your name. The note is kept with the decision and never written into the audit chain. |
ekka decide roles [--json] |
The roles your plans ask for, and how many people hold each. |
ekka decide approvers [--json] |
Who may answer which role's decisions. |
ekka decide grant <email> <role> |
Let a member answer a role's decisions. |
ekka decide revoke <email> <role> |
Stop a member answering a role's decisions. Anything already waiting is untouched. |
Organization memory¶
Where your agents' records are filed, and which system holds them. See Organization memory.
| Command | What it does |
|---|---|
ekka memory shelves [--json] |
The shelves this organization keeps. Empty on a new organization. |
ekka memory add <path> [--purpose <text>] |
Add a shelf, such as memory/hr/people. A path names a kind of record, never a customer or a case. |
ekka memory delete <path> |
Delete a shelf. Refused while any kind of record is still filed on it, and the refusal names them. |
ekka memory subjects [--json] |
Where each kind of record goes. |
ekka memory file <kind> <shelf> |
Say where one kind of record goes. The shelf has to exist first. |
ekka memory unfile <kind> |
Take back where one kind of record goes. What agents already wrote stays where it is. |
ekka memory bindings [--json] |
Which system holds each shelf. |
ekka memory bind <shelf> [--provider store] [--verbs list,read,write] |
Say which system holds a shelf. The default is the encrypted store inside your Enclave. A claim the system cannot meet is refused now, with the reason. |
ekka memory unbind <shelf> |
Stop a system holding a shelf. Plans that use those records stop, by name, until you bind it again. |
Charter¶
Your organization's own written principles, kept as a versioned record. Reading is open to every role; adopting and amending is for owners and admins. See Your Charter.
| Command | What it does |
|---|---|
ekka charter show [--version <n>] [--json] |
The Charter in force, with its version and the fingerprint an auditor checks it against. --version reads an older one, and says on the screen that it is not in force. |
ekka charter adopt <file.md> [--expect-version <n>] |
Adopt a Charter, or amend the one that stands. Amending adopts the next version and the old text stays readable. --expect-version refuses if somebody adopted in between, instead of overwriting their work. Text identical to what stands is refused. |
ekka charter history [--json] |
Every version ever adopted, newest first, with each fingerprint. |
# Adopt, then prove the fingerprint is a digest of your own file
ekka charter adopt charter.md
shasum -a 256 charter.md # sha256sum on Linux
Organizations and members¶
| Command | What it does |
|---|---|
ekka org list [--json] |
Every organization you belong to. The active one is marked. |
ekka org create <slug> [--name <name>] |
Create an organization and switch to it. |
ekka org switch <slug> |
Change which organization your commands act on. |
ekka org members list |
Who is in the organization, and their role. |
ekka org members invite <email> --role <role> |
Invite somebody by email. Nothing is shared until they accept. |
ekka org members resend <email> |
Resend a pending invitation. The role is unchanged. |
ekka org members set-role <email> <role> |
Change a member's role, one of admin, member or viewer. |
ekka org members cancel <email> |
Cancel a pending invitation. |
ekka org members remove <email> |
Remove a member from the organization. |
ekka org edition [--json] |
Which edition this organization is on, and what it includes. |
ekka org readiness [--json] |
What this organization still needs before it is fully set up: a red, yellow or green checklist with one next action. Green needs one run that actually finished. |
ekka org login-policy set <any\|sso\|sso_mfa> |
How this organization's people may sign in. The answer says when your own session is the first one the new policy will refuse. |
ekka org transfer <email> |
Hand the organization to another member, who must already belong to it. You become an admin, and the organization always has exactly one owner. Only the owner can do this. |
ekka org usage [--json] |
What this organization has run, metered, and what credit is left. |
ekka org delete <slug> --confirm <slug> |
Delete an organization that is still pending, or deactivate an active one. Receipts and audit history are retained. |
Spend ceilings and credit¶
| Command | What it does |
|---|---|
ekka org limits [--json] |
The spend ceilings this organization runs under, and which are EKKA's defaults versus its own. |
ekka org limits set <meter> <max> [--period <period>] |
Set this organization's own ceiling for one meter. Raises or lowers it. Admin only. |
ekka org limits remove <meter> [--period <period>] |
Give up this organization's own ceiling and go back to EKKA's default. Admin only. |
ekka org billing [--json] |
What credit this organization has left, and what it has spent this period. |
A ceiling bounds how much gets spent in a period. That is a different
question from ekka org edition, which shows the published limits on how much
can exist (seats, Enclaves, agents). EKKA stops work when a ceiling is
reached, so ekka org limits is the screen that answers "why was I refused".
ekka org limits marks every row as EKKA's default or as your own choice,
because who chose a number decides who can change it. remove prints the
default it went back to: removing your ceiling is not the same as having none.
Changing a ceiling is recorded
set and remove are admin decisions. Each one is written to your
organization's audit chain on the same transaction as the change, and the
owner is emailed even when the owner made the change. Read them back with
ekka audit list.
Credit is prepaid: work spends it, and when it runs out work stops. There
are no invoices and no card is kept on file for automatic charges. Credit is
added to your organization by the EKKA team, so write to
[email protected] to top up. ekka org usage shows the
balance beside what has actually been consumed. Prices are on
Pricing.
Switch before you delete
ekka org delete only resolves the active organization and answers "not
found" for any other. Switch to it first. Deleting the organization your
Enclave was claimed in is how a machine ends up bound to an Enclave that no
longer exists.
Environments and appearance¶
| Command | What it does |
|---|---|
ekka env list [--json] |
The environments this machine is enrolled in. |
ekka theme [dark\|light\|auto] |
Show the colors ekka prints with, or change them. Leave the value out to see what is set. NO_COLOR turns color off entirely. |
Secrets¶
The local Enclave vault. Values never appear on the command line and never leave
your machine, and they are encrypted at rest: even the filenames on disk
reveal nothing about what is stored, and the Enclave's own identity is kept the
same way. On macOS and Windows the sealing key lives in the OS keychain, so the
vault stays sealed if its files are copied off the machine; on Linux the key is
a permission-protected file, so full-disk encryption is still worth turning on.
Names must match ^[A-Z][A-Z0-9_]{2,127}$.
| Command | What it does |
|---|---|
ekka secret put <NAME> --stdin |
Store a secret, value read from stdin. |
ekka secret put <NAME> --from-env <ENV_NAME> |
Store a secret, value copied from an environment variable. |
ekka secret list [--json] |
List stored secret names and metadata (never values). |
ekka secret remove <NAME> |
Remove a secret (idempotent). |
Shell completion¶
| Command | What it does |
|---|---|
ekka completion <bash\|zsh\|fish> |
Print a shell-completion script for your shell. |