ablative docs
↑↓ move↵ openesc close
Stack Notebook ablative.com.au

Command line

All installed Lys CLI help entries, grouped by purpose, plus the version command.

Open .md

Global output and errors

The global JSON option asks for one structured success or failure answer. Read that answer and any named refusal as well as the process exit. The MCP bridge relays JSON-RPC results, including refusals, without converting every refused call into a process failure.

Some command groups require arguments in addition to the usage summary. Run the same command with its help flag to read every optional argument before performing a change. Version and help are safe inspection; install, issue, start, stop, set and import are changes.

Inspect the executable

Cryptographic trust infrastructure for AI agents — identity, attestation, and verification

lys [OPTIONS] <COMMAND>

Print the CLI version and source commit.

lys --version

Sign in and launch

Sign this terminal in as yourself, without installing an identity service

lys sign-in [OPTIONS] --server <BASE>
--server <BASE>
The server's HTTPS base, including /api; HTTP is allowed on loopback only.

Start your Claude agent on this machine through Lys and attach its terminal

lys claude [OPTIONS] [ARGUMENTS]...
[ARGUMENTS]...
Arguments for the harness, kept as separate words.

Start your Codex agent on this machine through Lys and attach its terminal

lys codex [OPTIONS] [ARGUMENTS]...
[ARGUMENTS]...
Arguments for the harness, kept as separate words.

Start your agent's reviewed command on this machine through Lys

lys run [OPTIONS] <COMMAND> [ARGUMENTS]...
<COMMAND>
The declared program or harness name to select.
[ARGUMENTS]...
Arguments for the program, kept as separate words.

Show your agents on this machine with their state and harness defaults

lys agents [OPTIONS]

Show a seat's live session in this terminal using its recorded transport: managed frames or the pseudo-terminal's exact bytes.

lys attach [OPTIONS] [SEAT]
[SEAT]
The seat whose session to show.

Identities and certificates

Identity key management

lys key [OPTIONS] <COMMAND>

Certificate-authority operations: issue and verify Ed25519-signed X.509 certificates

lys ca [OPTIONS] <COMMAND>

Sign an attestation over a payload file and write the `COSE_Sign1` artifact

lys attest [OPTIONS] --key <KEY> --payload <PAYLOAD> --out <OUT>
--key <KEY>
Path to the identity key file (raw 32-byte Ed25519 seed).
--payload <PAYLOAD>
Path to the payload file to attest.
--out <OUT>
Path to write the `COSE_Sign1` attestation artifact to (raw bytes; conventional extension .cose).

Verify a `COSE_Sign1` attestation artifact against a payload file, and optionally against the certificate that vouches for its signer.

lys verify [OPTIONS] --attestation <ATTESTATION> --payload <PAYLOAD>
--attestation <ATTESTATION>
Path to the `COSE_Sign1` attestation artifact produced by `lys attest`.
--payload <PAYLOAD>
Path to the payload file the attestation should cover.
--cert <CERT>
Path to the PEM certificate vouching for the attestation's signer (optional). Requires --issuer-public-key.
--issuer-public-key <ISSUER_PUBLIC_KEY>
Trusted issuer Ed25519 public key as 64 hexadecimal characters. Requires --cert.
--at <AT>
RFC 3339 instant to evaluate the certificate's validity window at (default: now).

Read-only viewers: print what an artifact or certificate file says, WITHOUT verifying any of it.

lys inspect [OPTIONS] <COMMAND>

Seal a payload for a recipient and sign the envelope with the sender's identity (X25519 + HKDF-SHA256 + AES-256-GCM, Ed25519 attestation over the sealed bytes).

lys seal [OPTIONS] --key <KEY> --recipient-public-key <RECIPIENT_PUBLIC_KEY> --payload <PAYLOAD> --out <OUT> --attestation-out <ATTESTATION_OUT>
--key <KEY>
Path to the sender's identity key file (raw 32-byte Ed25519 seed).
--recipient-public-key <RECIPIENT_PUBLIC_KEY>
Recipient X25519 public key as 64 hexadecimal characters — the `public key (x25519)` line printed by `lys key inspect`.
--payload <PAYLOAD>
Path to the payload file to seal.
--out <OUT>
Path to write the JSON sealed envelope to.
--attestation-out <ATTESTATION_OUT>
Path to write the sender's `COSE_Sign1` attestation to (raw bytes; conventional extension .cose).

Open a sealed envelope, verifying the sender attestation before decrypting. The plaintext is written to --out, never to stdout.

lys open [OPTIONS] --key <KEY> --sender-public-key <SENDER_PUBLIC_KEY> --envelope <ENVELOPE> --attestation <ATTESTATION> --out <OUT>
--key <KEY>
Path to the recipient's identity key file (raw 32-byte Ed25519 seed).
--sender-public-key <SENDER_PUBLIC_KEY>
Expected sender Ed25519 public key as 64 hexadecimal characters — the `public key (ed25519)` line printed by `lys key inspect`.
--envelope <ENVELOPE>
Path to the JSON sealed envelope produced by `lys seal`.
--attestation <ATTESTATION>
Path to the `COSE_Sign1` sender attestation produced by `lys seal`.
--out <OUT>
Path to write the decrypted payload to (created mode 0600 on Unix).

Generate a new Ed25519 identity key, or load the existing one if the file is already present. Prints the public key; never prints private key material

lys key generate [OPTIONS] --out <OUT>
--out <OUT>
Path to write the identity key file to (raw 32-byte seed, mode 0600 on Unix).

Inspect an existing identity key file: print the Ed25519 public key and the derived X25519 public key. Never prints private key material

lys key inspect [OPTIONS] --key <KEY>
--key <KEY>
Path to the identity key file (raw 32-byte Ed25519 seed).

Create a PKCS#10 certificate-signing request for your own identity key and write it as PEM.

lys ca request [OPTIONS] --key <KEY> --subject <SUBJECT> --out <OUT>
--key <KEY>
Path to your identity key file (raw 32-byte Ed25519 seed).
--subject <SUBJECT>
Common name to request a certificate under.
--out <OUT>
Path to write the PEM-encoded certificate-signing request to.

Issue an Ed25519-signed X.509 certificate for a named subject and write it as PEM.

lys ca issue [OPTIONS] --key <KEY> --subject <SUBJECT> --out <OUT> --log <LOG> --leaf-out <LEAF_OUT> <--validity <VALIDITY>|--validity-days <VALIDITY_DAYS>>
--key <KEY>
Path to the issuing authority's identity key file (raw 32-byte Ed25519 seed).
--subject <SUBJECT>
Subject common name to issue the certificate for.
--request <REQUEST>
Path to a PEM certificate-signing request from the subject (optional).
--validity <VALIDITY>
Validity window from now as a count and one unit: s, m, h, or d (notBefore = now, notAfter = now + this).
--validity-days <VALIDITY_DAYS>
Validity window length in whole days from now (notBefore = now, notAfter = now + this many days).
--out <OUT>
Path to write the PEM-encoded certificate to.
--log <LOG>
Transparency log directory to enter the certificate in before it is written, as one leaf whose bytes are the certificate's DER.
--leaf-out <LEAF_OUT>
Path to write the leaf to: the certificate's DER bytes exactly.

Write the issuer's self-signed CA certificate as PEM.

lys ca issuer-cert [OPTIONS] --key <KEY> --out <OUT>
--key <KEY>
Path to the issuing authority's identity key file (raw 32-byte Ed25519 seed).
--out <OUT>
Path to write the PEM-encoded issuer certificate to.

Verify a PEM certificate against a trusted issuer public key at a given instant.

lys ca verify [OPTIONS] --cert <CERT> --issuer-public-key <ISSUER_PUBLIC_KEY>
--cert <CERT>
Path to the PEM certificate produced by `lys ca issue`.
--issuer-public-key <ISSUER_PUBLIC_KEY>
Trusted issuer Ed25519 public key as 64 hexadecimal characters, as printed by `lys key inspect`.

Print the fields of a `COSE_Sign1` attestation artifact WITHOUT checking its signature.

lys inspect attestation [OPTIONS] --attestation <ATTESTATION>
--attestation <ATTESTATION>
Path to the `COSE_Sign1` attestation artifact produced by `lys attest`.

Print a PEM certificate's fields and capability claims WITHOUT checking it against any issuer.

lys inspect cert [OPTIONS] --cert <CERT>
--cert <CERT>
Path to the PEM certificate produced by `lys ca issue`.

Transparency logs

Transparency-log operations: append-only logs with C2SP signed-note checkpoints and self-contained RFC 6962 proof artifacts.

lys log [OPTIONS] <COMMAND>

Initialize a new log directory, pinning its origin.

lys log init [OPTIONS] --dir <DIR> --origin <ORIGIN>
--dir <DIR>
Path to the log directory to create.
--origin <ORIGIN>
The log origin pinned at creation. Choose the exact origin independently of the signing key.

Report a log's origin, size and current root hash — without its key.

lys log status [OPTIONS] --dir <DIR>
--dir <DIR>
Path to the log directory to inspect.

Append a leaf file's raw bytes to the log.

lys log append [OPTIONS] --dir <DIR> --leaf <LEAF>
--dir <DIR>
Path to an initialized log directory.
--leaf <LEAF>
Path to the leaf file whose raw bytes are appended.

Sign a C2SP signed-note checkpoint over the log's current root and write it to a file.

lys log checkpoint [OPTIONS] --dir <DIR> --key <KEY> --out <OUT>
--dir <DIR>
Path to an initialized log directory.
--key <KEY>
Path to the log operator's identity key file (raw 32-byte Ed25519 seed).
--out <OUT>
Path to write the signed checkpoint note to.

Build a self-contained, signed JSON proof artifact

lys log prove [OPTIONS] <COMMAND>

Verify a proof artifact as a third party.

lys log verify [OPTIONS] <COMMAND>

Build an inclusion-proof artifact for one leaf, embedding a freshly signed checkpoint of the current tree

lys log prove inclusion [OPTIONS] --dir <DIR> --key <KEY> --leaf-index <LEAF_INDEX> --out <OUT>
--dir <DIR>
Path to an initialized log directory.
--key <KEY>
Path to the log operator's identity key file (raw 32-byte Ed25519 seed).
--leaf-index <LEAF_INDEX>
Zero-based index of the leaf to prove.
--out <OUT>
Path to write the JSON inclusion-proof artifact to.

Build a consistency-proof artifact from an earlier tree size to the current tree, embedding freshly signed checkpoints of both

lys log prove consistency [OPTIONS] --dir <DIR> --key <KEY> --old-size <OLD_SIZE> --out <OUT>
--dir <DIR>
Path to an initialized log directory.
--key <KEY>
Path to the log operator's identity key file (raw 32-byte Ed25519 seed).
--old-size <OLD_SIZE>
The earlier tree size to prove consistency from.
--out <OUT>
Path to write the JSON consistency-proof artifact to.

Verify an inclusion-proof artifact against a leaf file.

lys log verify inclusion [OPTIONS] --artifact <ARTIFACT> --leaf <LEAF> --verifier-key <VERIFIER_KEY>
--artifact <ARTIFACT>
Path to the JSON inclusion-proof artifact produced by `lys log prove inclusion`.
--leaf <LEAF>
Path to the raw leaf file the artifact should prove.
--verifier-key <VERIFIER_KEY>
Trusted verifier key string in the signed-note format `ORIGIN+KEYID_HEX+KEY_BASE64`, as printed by `lys log checkpoint` and `lys key inspect --note-name`.

Verify a consistency-proof artifact.

lys log verify consistency [OPTIONS] --artifact <ARTIFACT> --verifier-key <VERIFIER_KEY>
--artifact <ARTIFACT>
Path to the JSON consistency-proof artifact produced by `lys log prove consistency`.
--verifier-key <VERIFIER_KEY>
Trusted verifier key string in the signed-note format `ORIGIN+KEYID_HEX+KEY_BASE64`, as printed by `lys log checkpoint` and `lys key inspect --note-name`.

Installed identity product

The standalone identity product's dependencies: prepare the private deployment artifacts, configure Rauthy's clients and themes, and check readiness

lys identity [OPTIONS] <COMMAND>

Import apps, agents and delegated permissions using a service account's own credential. Stops at the first named refusal

lys identity import [OPTIONS] <FILE>
<FILE>
The JSON document to import.

Validate the deployment configuration and materialise its private artifacts: generated or provided credentials and the compose environment, each owner-only in the state directory. Existing credentials are reused, never rotated

lys identity prepare [OPTIONS] --config <CONFIG>
--config <CONFIG>
The deployment configuration (see deploy/identity/config.example.toml).

Register the platform's and the installed app's clients in Rauthy and apply their themes. Idempotent: a second run changes nothing and reports the same operation identifiers. Rauthy's built-in client is never touched

lys identity configure [OPTIONS] --config <CONFIG>
--config <CONFIG>
The deployment configuration.

Install the whole identity product for this user: a data folder under the application data path, generated keys and configuration, the compose services, the platform's client, the secrets broker and the directory service with its screens, then opens Lys's setup page. Nothing is filled from the machine. Running it again changes only what is missing and restarts only what it changed; nothing is rotated, and a build other than the one placed is refused: that is an upgrade

lys identity install [OPTIONS]

Upgrade a running install to the binaries in a folder, run with the lys built beside them: finish or put back an upgrade stopped part-way, check each binary's --version, render the new build's configuration and compose files, stop the service and the broker, keep the running binaries in bin.previous/ and the files in config.previous/, place the new ones, bring changed compose services to their new definition and start the new build. When anything does not start or become ready, the previous build is put back and started, and the failure is named. Data and credentials are never touched. An install made before builds were named is adopted

lys identity upgrade [OPTIONS] --from <FROM>
--from <FROM>
The folder holding the newly built lys-secrets and lys-identity-server, built with the lys that runs the upgrade.

Turn off everything Lys started: ask the service to stop every session on every computer it drives, recording on each who pulled the cord and why; tell this computer's runner the same; stop the runner, the model proxy, the service and the broker; then stop the database, sign-in and permission services, keeping their data. Every part is done whatever an earlier part answered, and each that failed is named. Sessions are hung up and waited on until each has ended; --kill, or a second stop while sessions still run, ends them at once

lys identity stop [OPTIONS] --reason <REASON>
--reason <REASON>
Why everything is stopped, in your words; kept on every session.

Start whatever of the install is down, as the install starts it, and leave running whatever runs: the inverse of stop. A stop of everything pulled in the service stays pulled until the administrator lets agents start again

lys identity start [OPTIONS]

Write a fresh one-time setup code and open the setup page with it, so the administrator sets a new password; or, before first-run setup has finished, a fresh first-run code. Requires a macOS Touch ID or device-password prompt. The code is never printed

lys identity setup-code [OPTIONS]

Check that `PostgreSQL`, Rauthy and `SpiceDB` are ready, naming each one that is not. Prints no credential

lys identity health [OPTIONS] --config <CONFIG>
--config <CONFIG>
The deployment configuration.

Runners and model proxy

Lys's own runner: holds each agent the server starts in its own background pseudo-terminal, reached on a Unix socket only, and the bridge a runner on another machine dials the server through

lys runner [OPTIONS] <COMMAND>

Lys's model proxy: every model call a Lys-started run makes goes through it to the provider unchanged, and is recorded under its run

lys proxy [OPTIONS] <COMMAND>

Start the runner using this computer's saved connection, without a code

lys runner start [OPTIONS]

Connect this computer once and install its native login service

lys runner install [OPTIONS]

Remove the login service while keeping this computer's saved connection

lys runner uninstall [OPTIONS]

Verify and install the server's release, keeping the previous runner

lys runner update [OPTIONS]

Hold each agent the server starts in its own background pseudo-terminal.

lys runner serve [OPTIONS] --socket <SOCKET> --state <STATE> --server-key <SERVER_KEY>
--socket <SOCKET>
The Unix socket to listen on.
--state <STATE>
The directory the record of held sessions is kept in.
--server-key <SERVER_KEY>
A file holding the server's Ed25519 public key as 64 hexadecimal characters.

Relay the server's requests to this machine's runner, dialling the server with the machine's own key; the server never dials a runner on another machine.

lys runner dial [OPTIONS] --socket <SOCKET> --server <SERVER> --machine <MACHINE> --machine-key <MACHINE_KEY>
--socket <SOCKET>
This machine's runner's Unix socket.
--server <SERVER>
The server's address: https://host:port and any path prefix.
--machine <MACHINE>
This machine's id, as the server's records name it.
--machine-key <MACHINE_KEY>
The machine's own key file (raw 32-byte Ed25519 seed); its public half is the key the machine's runner record names.

Join this computer to Lys as the runner of a computer Lys names, with the connection code Lys gave for it, then serve and dial as `lys runner serve` and `lys runner dial` do, for as long as this command runs.

lys runner join [OPTIONS] --server <SERVER> --machine <MACHINE>
--server <SERVER>
The server's address: https://host:port and any path prefix, as Lys gave it.
--machine <MACHINE>
This computer's id, as Lys names it.

Judge one tool call for a session's harness: the `PreToolUse` hook command. Reads the hook's input on standard input, asks the runner on --socket, and writes the harness's answer on standard output. Any failure, from malformed input to a runner that cannot be reached, is written as a deny with its reason; the command itself exits zero so the harness reads that deny

lys runner judge [OPTIONS] --socket <SOCKET> --harness <HARNESS>
--socket <SOCKET>
The runner's Unix socket.
--harness <HARNESS>
The harness whose hook wire is read and written Possible values: - claude: Claude Code - codex: Codex.

Hand a run's status line to its runner: the command a run counted through the proxy is given as its harness's status line. Reads the harness's input on standard input, hands it to the runner on --socket, and writes one line for the harness to show: that Lys counts the run, or that its dollars and running time were not counted and why

lys runner status-line [OPTIONS] --socket <SOCKET>
--socket <SOCKET>
The runner's Unix socket.

Hand Claude Code's hook JSON from stdin to the runner. Every outcome exits zero with no stdout; failures are named on stderr

lys runner hook [OPTIONS] --socket <SOCKET>
--socket <SOCKET>
The runner's Unix socket.

Hand Codex's appended notification JSON to the runner. Only agent-turn-complete is sent; every outcome exits zero with no stdout

lys runner notify [OPTIONS] --socket <SOCKET> <NOTIFICATION>
<NOTIFICATION>
The notification JSON appended by Codex.
--socket <SOCKET>
The runner's Unix socket.

Forward each model call unchanged and record it under its run.

lys proxy serve [OPTIONS] --listen <LISTEN> --home <HOME> --state <STATE>
--listen <LISTEN>
The loopback address to listen on.
--home <HOME>
The home the calls are recorded in.
--state <STATE>
Where the open-call journal and the capture spool live.

Seats, agent passes and variables

A Lys-started run's own variables: read and patch its agent's map and its session's map, as the run itself, by the run pass Lys rendered into the seat's own configuration. The pass is read from the launch's mcp.json (a Claude Code seat) or from `LYS_AGENT_PASS` and `LYS_MCP_URL` (a Codex seat), and is never printed

lys variables [OPTIONS] <COMMAND>

Seats: an agent identity's standing place on a machine, held by the installed identity server, which starts it through its machine's runner with the reviewed profile's transport.

lys seat [OPTIONS] <COMMAND>

An agent's own acts against the installed identity server, made with the agent's own credential and never the operator token

lys agent [OPTIONS] <COMMAND>

Read the run's agent map, or with --session its session map: each variable with its revision, author and expiry, and the scope's revision to carry on the next set

lys variables get [OPTIONS]

Patch the map: each key=value sets a key (a JSON value when it parses as one, else the text), key= alone removes it; the revision read must be given, and a stale one is refused by name

lys variables set [OPTIONS] --revision <REVISION> <VALUES>...
<VALUES>...
The keys, as key=value or key= to remove.
--revision <REVISION>
The scope revision read; 0 for a map never patched.

Add a seat: a name, the agent it runs as, a reviewed profile version, and the machine whose runner holds it

lys seat add [OPTIONS] --agent <AGENT> --profile-version <PROFILE_VERSION> --machine <MACHINE> <NAME>
<NAME>
The seat's name: lowercase letters, digits and '-', 1 to 64, unique in the install.
--agent <AGENT>
The agent identity the seat runs as.
--profile-version <PROFILE_VERSION>
The reviewed version of the agent's profile the seat starts with.
--machine <MACHINE>
The machine whose runner holds the seat.

List every seat with its state and last signal, and whether the runner could be read; a runner that could not is named with its reason

lys seat list [OPTIONS]

Start a seat's session through the server's own start path with the reviewed profile's transport

lys seat start [OPTIONS] <NAME>
<NAME>
The seat.

Stop a seat's session: the harness is asked to end when idle, and a turn in progress is refused `seat_turn_in_progress` unless --force

lys seat stop [OPTIONS] <NAME>
<NAME>
The seat.

Stop a seat's session, then start it again

lys seat restart [OPTIONS] <NAME>
<NAME>
The seat.

Send a message to a running seat as a user turn, never as typed keys. Text that is empty or carries control characters is refused by name

lys seat send [OPTIONS] <NAME> <TEXT>...
<NAME>
The seat.
<TEXT>...
The message; its words are joined with single spaces.

Import one seat's existing configuration by a confirmed, restartable plan: a dry run that changes nothing, then the person's confirmation of that exact plan. Importing never starts, stops or restarts a seat

lys seat import [OPTIONS] <COMMAND>

Ask for the agent's pass to an approved app, carrying the agent's own grants on that app's kinds, and write it to a file only its owner may read, for a tool to present to the app.

lys agent pass [OPTIONS] --agent <ID> --audience <APP> --credential-file <PATH> --out <PATH>
--agent <ID>
The agent identity the pass is for.
--audience <APP>
The app the pass is for: an app approved on the Apps screen.
--credential-file <PATH>
The file holding the grant credential, owner-only.
--out <PATH>
The file to write the pass to, created owner-only (mode 0600).

Read the seat's declared sources at one instant and show the whole plan: its sources and revisions, every record it writes, credential references, replacements, schedule counts, exclusions, prerequisites and refusals. Nothing is sent, started or changed

lys seat import dry-run [OPTIONS] --manifest <PATH> <NAME>
<NAME>
The seat.
--manifest <PATH>
The JSON manifest naming the seat's sources.

Confirm the exact plan a dry run showed, as the person responsible, and apply it under one operation that resumes after a stop

lys seat import confirm [OPTIONS] --plan <ID> --revision <REVISION> <NAME>
<NAME>
The seat.
--plan <ID>
The plan id the dry run showed.
--revision <REVISION>
The plan revision the dry run showed.

Show every import of the seat and the one selected

lys seat import status [OPTIONS] <NAME>
<NAME>
The seat.

Agent MCP bridge

An agent's own MCP connection to Lys, over stdio: each JSON-RPC message read on stdin is signed with the agent's key (`lys-agent-signature`) and posted to Lys's MCP route, and the answer written on stdout. Calls carry the agent's own grants and meet Lys's own refusals; the bridge grants nothing. The key is never printed

lys mcp [OPTIONS] --url <URL> --agent <AGENT> --key-file <KEY_FILE>
--url <URL>
The installed Lys MCP route on numeric loopback HTTP, such as http://127.0.0.1:8490/api/mcp.
--agent <AGENT>
The agent the messages are signed as (`agent-…`).
--key-file <KEY_FILE>
The agent's key: a PKCS#8 PEM file, or a seat file whose `privateKeyPem` holds it.
Lys 0.3.1