keygen-cli
A Rust CLI for keygen.sh. One binary, three deployments
(Cloud / self-hosted CE / self-hosted EE), and a stable JSON envelope built for
agents. Every command emits the same { ok, data, meta?, error? } shape under
--json, and exit codes are documented and stable.
Setup
brew install okooo5km/tap/keygen-cli # installs `keygen` and the `kg` alias
keygen --version
Other paths (pre-built tarballs, cargo install, source) live in
references/installation.md.
Authenticate
keygen login # interactive: deployment → host → account → token
keygen whoami # confirm identity + detected capabilities
Tokens land in the OS keyring (Keychain on macOS, Secret Service on Linux,
Credential Manager on Windows). For CI and ephemeral shells, set
KEYGEN_TOKEN=... instead — that path skips the keyring entirely. Switch
deployments with --profile <name> or KEYGEN_PROFILE.
Core invocation pattern
Every resource exposes the same CRUD surface. Resource-specific actions
(validate, suspend, publish, ...) sit on the same subcommand tree.
keygen <resource> list [--filter k=v] [--limit N] [--page N] [--sort field]
keygen <resource> get <id>
keygen <resource> create [--from-file body.json | --set attrs.x=y --metadata k=v]
keygen <resource> update <id> [--from-file body.json | --set ...]
keygen <resource> delete <id> --yes
Two examples:
keygen license list --filter status=ACTIVE --json
keygen license create --json --policy pol_abc --user usr_def --set attrs.name="Acme"
--json (a gh-style shortcut for --output json) always emits the canonical
envelope. Exit codes: 0 ok, 1 user, 2 server, 3 network, 4 auth, 5
capability. Full envelope schema in
references/ai-envelope.md.
Self-discovery
Two commands let an agent learn the full surface area without reading docs:
keygen schema --format json # entire command tree (subcommands + flags)
keygen explain error <CODE> # diagnose any keygen.sh error code
Use schema when you need to verify a flag exists or look up a subcommand.
Use explain whenever an envelope returns error.code — it returns the
canonical cause, fix, and a suggested next command.
Permission tiers
Three tiers govern which operations need human approval. The full per-command
list is in references/permissions.md; apply
the rules below verbatim.
Tier 1 — auto-run
Read-only inspection. Run freely, no confirmation required.
list, get on every resource.
whoami, doctor, schema, explain, config get, profile list.
*-log list / *-log get (request-log, event-log).
webhook event list / webhook event get.
Tier 2 — dry-run, then confirm
Mutating but reversible (or low-blast-radius). On the first invocation,
add --dry-run --json, show the user the request envelope (method + URL +
body), and proceed only after the user agrees.
create and update on every resource.
license validate, machine activate, machine ping, process spawn,
process ping.
license usage incr|decr|reset.
license check-out, license check-in, machine check-out.
artifact download, artifact upload (when uploading a brand-new file).
webhook endpoint test, webhook event retry.
release upgrade (read-only computation, but billable on Cloud — confirm).
Tier 3 — explicit approval, no shortcuts
Destructive or irreversible. Never pass --yes until the user has verbally
agreed to the exact command and target id. Restate the command and its
blast radius first.
delete on every resource.
license suspend, license reinstate, license renew, license revoke,
license transfer.
release publish, release yank, artifact yank.
user ban, user unban, user reset-password, user update-password.
process kill.
token regenerate.
- Any mutation aimed at a profile whose name contains
prod / production,
or the unnamed default profile when the host is api.keygen.sh.
Risk heuristics
Before running a Tier 2 or Tier 3 operation, raise the concern first if any
of these hold:
- The active profile looks like production (
prod, production, or the
default profile pointing at api.keygen.sh).
- The batch covers five or more resource ids.
- A write request lacks
--idempotency-key and the user has not opted into
retries being unsafe.
- The user asked for
delete / revoke without a recent get of the target.
- The command is EE-only (
event-log, request-log, env) but keygen doctor reports CE/Cloud — surface the capability mismatch instead of
hitting the API.
- Running
<resource> list --filter <relation>=<id> against a self-hosted
CE deployment without first running keygen doctor. Some CE versions
ignore relation filters silently; doctor's filters_relation check
surfaces the gap before you trust a result set.
Common patterns
# Issue a perpetual license for a known policy + user.
keygen license create --json \
--policy pol_abc --user usr_def \
--set attrs.name="Acme — Pro 2026" --metadata seat=enterprise
# Activate a machine and then ping it.
keygen machine activate --json --license lic_xyz --fingerprint $(uname -n)
keygen machine ping --json <machine_id>
# Cut a release and upload its binary.
keygen release create --json --product prod_abc --set attrs.version=1.4.0
keygen artifact upload --json --release rel_xyz --file ./dist/app-1.4.0.dmg
Walk-throughs:
examples/create-license.md,
examples/offline-verify.md.
Where to dig deeper
1---2name: keygen-cli3description: keygen-cli — manage keygen.sh from the command line: products, policies, licenses, machines, releases, artifacts, webhooks, users, and tokens. Works against keygen.sh Cloud, self-hosted CE, and self-hosted EE. Use this skill whenever the user mentions: keygen.sh, license management, software licensing, license key, license activation, activate machine, suspend license, revoke license, renew license, release artifact upload, webhook endpoint, entitlement, policy, product token, offline license verify. All write operations require explicit human approval — see references/permissions.md for the three-tier rule set.4license: MIT5---67# keygen-cli89A Rust CLI for [keygen.sh](https://keygen.sh). One binary, three deployments10(Cloud / self-hosted CE / self-hosted EE), and a stable JSON envelope built for11agents. Every command emits the same `{ ok, data, meta?, error? }` shape under12`--json`, and exit codes are documented and stable.1314## Setup1516```bash17brew install okooo5km/tap/keygen-cli # installs `keygen` and the `kg` alias18keygen --version19```2021Other paths (pre-built tarballs, `cargo install`, source) live in22[`references/installation.md`](./references/installation.md).2324## Authenticate2526```bash27keygen login # interactive: deployment → host → account → token28keygen whoami # confirm identity + detected capabilities29```3031Tokens land in the OS keyring (Keychain on macOS, Secret Service on Linux,32Credential Manager on Windows). For CI and ephemeral shells, set33`KEYGEN_TOKEN=...` instead — that path skips the keyring entirely. Switch34deployments with `--profile <name>` or `KEYGEN_PROFILE`.3536## Core invocation pattern3738Every resource exposes the same CRUD surface. Resource-specific actions39(validate, suspend, publish, ...) sit on the same subcommand tree.4041```bash42keygen <resource> list [--filter k=v] [--limit N] [--page N] [--sort field]43keygen <resource> get <id>44keygen <resource> create [--from-file body.json | --set attrs.x=y --metadata k=v]45keygen <resource> update <id> [--from-file body.json | --set ...]46keygen <resource> delete <id> --yes47```4849Two examples:5051```bash52keygen license list --filter status=ACTIVE --json53keygen license create --json --policy pol_abc --user usr_def --set attrs.name="Acme"54```5556`--json` (a `gh`-style shortcut for `--output json`) always emits the canonical57envelope. Exit codes: `0` ok, `1` user, `2` server, `3` network, `4` auth, `5`58capability. Full envelope schema in59[`references/ai-envelope.md`](./references/ai-envelope.md).6061## Self-discovery6263Two commands let an agent learn the full surface area without reading docs:6465```bash66keygen schema --format json # entire command tree (subcommands + flags)67keygen explain error <CODE> # diagnose any keygen.sh error code68```6970Use `schema` when you need to verify a flag exists or look up a subcommand.71Use `explain` whenever an envelope returns `error.code` — it returns the72canonical cause, fix, and a suggested next command.7374## Permission tiers7576Three tiers govern which operations need human approval. The full per-command77list is in [`references/permissions.md`](./references/permissions.md); apply78the rules below verbatim.7980### Tier 1 — auto-run8182Read-only inspection. Run freely, no confirmation required.8384- `list`, `get` on every resource.85- `whoami`, `doctor`, `schema`, `explain`, `config get`, `profile list`.86- `*-log list` / `*-log get` (request-log, event-log).87- `webhook event list` / `webhook event get`.8889### Tier 2 — dry-run, then confirm9091Mutating but reversible (or low-blast-radius). On the **first** invocation,92add `--dry-run --json`, show the user the request envelope (method + URL +93body), and proceed only after the user agrees.9495- `create` and `update` on every resource.96- `license validate`, `machine activate`, `machine ping`, `process spawn`,97 `process ping`.98- `license usage incr|decr|reset`.99- `license check-out`, `license check-in`, `machine check-out`.100- `artifact download`, `artifact upload` (when uploading a brand-new file).101- `webhook endpoint test`, `webhook event retry`.102- `release upgrade` (read-only computation, but billable on Cloud — confirm).103104### Tier 3 — explicit approval, no shortcuts105106Destructive or irreversible. Never pass `--yes` until the user has verbally107agreed to the *exact* command and target id. Restate the command and its108blast radius first.109110- `delete` on every resource.111- `license suspend`, `license reinstate`, `license renew`, `license revoke`,112 `license transfer`.113- `release publish`, `release yank`, `artifact yank`.114- `user ban`, `user unban`, `user reset-password`, `user update-password`.115- `process kill`.116- `token regenerate`.117- Any mutation aimed at a profile whose name contains `prod` / `production`,118 or the unnamed default profile when the host is `api.keygen.sh`.119120## Risk heuristics121122Before running a Tier 2 or Tier 3 operation, raise the concern *first* if any123of these hold:124125- The active profile looks like production (`prod`, `production`, or the126 default profile pointing at `api.keygen.sh`).127- The batch covers five or more resource ids.128- A write request lacks `--idempotency-key` and the user has not opted into129 retries being unsafe.130- The user asked for `delete` / `revoke` without a recent `get` of the target.131- The command is EE-only (`event-log`, `request-log`, `env`) but `keygen132 doctor` reports CE/Cloud — surface the capability mismatch instead of133 hitting the API.134- Running `<resource> list --filter <relation>=<id>` against a self-hosted135 CE deployment without first running `keygen doctor`. Some CE versions136 ignore relation filters silently; doctor's `filters_relation` check137 surfaces the gap before you trust a result set.138139## Common patterns140141```bash142# Issue a perpetual license for a known policy + user.143keygen license create --json \144 --policy pol_abc --user usr_def \145 --set attrs.name="Acme — Pro 2026" --metadata seat=enterprise146147# Activate a machine and then ping it.148keygen machine activate --json --license lic_xyz --fingerprint $(uname -n)149keygen machine ping --json <machine_id>150151# Cut a release and upload its binary.152keygen release create --json --product prod_abc --set attrs.version=1.4.0153keygen artifact upload --json --release rel_xyz --file ./dist/app-1.4.0.dmg154```155156Walk-throughs:157[`examples/create-license.md`](./examples/create-license.md),158[`examples/offline-verify.md`](./examples/offline-verify.md).159160## Where to dig deeper161162- [`references/installation.md`](./references/installation.md) — every install path.163- [`references/commands.md`](./references/commands.md) — full resource × action matrix.164- [`references/permissions.md`](./references/permissions.md) — authoritative tier list.165- [`references/ai-envelope.md`](./references/ai-envelope.md) — JSON shape + exit codes.166- [`references/tui.md`](./references/tui.md) — `keygen tui` keybindings and panels.167- [`references/recipes.md`](./references/recipes.md) — task-oriented cookbook168 (support, audit, release, batch ops, offline verify, troubleshooting).