aster.ax / Docs

Access and execution accounts

Deploying a runner establishes two things: which client may ask it to run work, and which OS account runs that work.

Optional owner setup

This step is optional because ax deploy ssh will do this one-time setup if it hasn't been done.

Run it early only if you want to see or back up the identities before deploying:

ax admin setup
ax admin setup --profile work --format json

The command prints the profile name, root public key and local node ID. Repeating it preserves the same keys, and first deployment reuses identities from admin setup when they exist.

The root key signs owner credentials; the node key identifies this machine's transport connections. Admin setup prepares local transport enrollment and a root-signed grant allowing this node to register its local agents. It starts no service and publishes no remote Exec grant. The broker starts when needed and shares one existing node with Exec. If an established key is missing or disagrees with recorded public identity, setup refuses to replace it. Restore the matching backup rather than generating a replacement for that profile.

Back up the root key to a new protected file and keep it offline:

ax key root export --out root-backup.key

What SSH deployment configures

ax deploy ssh uses your SSH access to install and configure the runner. The client keeps the owner's root key and its own node key. The runner has a distinct node key and receives the trust and execution policy needed to accept this client. Private node keys stay on their respective machines.

The deployment saves the runner's identity and local name. Later ax exec commands use authenticated ax connections and the installed policy; they do not start a new SSH session for each command. An address or saved alias alone grants no execution permission.

Keep the client's ax state directory, normally ~/.ax, private. On macOS, root-key storage uses the system keystore by default. Node keys and credentials also have protected local files; do not copy the whole directory to another machine as an onboarding shortcut.

Agent identities and message acceptance

After deployment, run ax agent setup --name assistant --workspace /absolute/path in the agent's workspace on the deployed machine, with the intended workspace explicitly selected. The service authorizes the configured payload account through Unix peer credentials and signs the public registration using its node grant. The agent never reads the service node key or creates another owner root. On an owner machine, optional ax admin setup configures the same registration path.

Setup preserves the private agent key outside the workspace and writes nonsecret TOML selection data to agent.ax.toml; parse it as data, never source it. Repeat setup preserves identity for the same name and rejects a changed node assignment. A different name creates a separate mailbox; it does not rename the existing one. Agents sharing one OS account share cooperative authority; this is not a sandbox.

ax agent list shows active local registrations and session status. Repeating setup with the same name and workspace restores a missing selection using the retained key. If a failed setup left an unregistered selection, recovery backs that selection up under the private agent key directory before replacing it. A selection belonging to another retained registration is never replaced.

Use ax agent move NAME --workspace /correct/path to correct an accidental workspace assignment while preserving identity and messages. Move removes the old session binding; when run from Claude's Bash tool it attaches the current session, otherwise run setup from the intended conversation. Use ax agent remove NAME to revoke an accidental registration. Removal keeps keys, messages and revocation records, and releases the name for a fresh identity. The removed key cannot register again. Repeat an interrupted move or remove with the same arguments to finish local cleanup. These commands require the existing authorized local account; they are not remote management endpoints.

Setup prints the registered name and workspace. Use --json or --format json for the structured result. In a Git working tree, setup preserves existing ignore rules and adds /agent.ax.toml to the workspace's .gitignore when needed. If the file is already tracked, setup warns instead of removing it from Git; run git rm --cached -- agent.ax.toml and repeat setup. A warning about an unsafe or unwritable .gitignore also leaves registration intact and asks you to fix the exclusion. Workspaces outside Git do not need an ignore file.

Use ax send assistant "Hello" for another agent on this machine, or ax send host/assistant "Hello" for an agent on another host. Both send as the selected local workspace agent. Use ax admin send host/assistant "Hello" as the owner root. Saved host aliases from deployment or ax exec alias NAME NODE_ID select the existing node. The sender can sign a host/mailbox-name destination while the host is offline. The receiving node assigns it once to that mailbox; later name reuse cannot redirect the retained message. Exact-key destinations, including replies, preserve their recipient key. No Exec grant is required for messaging.

Retain the message ID printed by send. The sender daemon saves the signed message before forwarding and retries offline hosts for three days, with exponential backoff capped around five minutes. Peer connection events trigger immediate forwarding. "Queued locally" and "accepted for delivery" are distinct: only the receiving host's durable receipt establishes acceptance. After acceptance, that host owns local agent delivery even if the sender disconnects.

Use ax messages status ID for the original message. Lost acknowledgements do not justify creating a new ID. CLI interruption stops foreground observation; explicit cancellation is separate. ax messages inbox inspects the selected local agent's inbox. There is no root-wide correspondence listing.

The owner can manage this node's retained message records:

ax admin status
ax admin status MESSAGE_ID
ax admin status --all --format json
ax admin cancel MESSAGE_ID

The default list shows outstanding messages; --all includes terminal records. Status distinguishes waiting for host, delivered to host, delivered to agent, cancellation pending, cancelled, expired and permanent failure. Detail explains retry/deadline information and any uncertain destination acceptance. Expiry after a lost receipt does not establish that the agent never received the message. The forwarding deadline does not expire messages already accepted by the receiver.

Cancellation is repeatable. Before any possible transmission it completes locally; otherwise it needs the receiving host's acknowledgement and may remain pending. At the receiver, cancellation prevents subsequent fetch. If fetch committed first, ax reports that the message was already delivered to the agent and cannot be cancelled. Neither cancellation nor delivery deletes the retained record.

Fetch and inbox show the authenticated sender name, key and node and a reply command. From the receiving workspace run ax reply MESSAGE_ID "Your response". The reply targets the original agent on its original node without requiring a return host alias. It keeps the conversation ID and records the original message as its parent. A removed sender or a name now owned by another key cannot receive that reply. Owner-authored messages show owner and cannot receive replies because the owner has no agent mailbox. Looking up a reply does not mark pickup.

JSON fetch and inbox use the same compact {message, receipt} object (inbox returns an array). The message includes sender with kind, name, key, node, address, and reply.command or reply.unavailable. Inbox no longer returns internal envelope/receipt tuples. Message text appears once; proofs and signatures remain private host state.

A receipt proves durable acceptance. When setup runs through Claude Code's Bash tool, it captures that conversation's exported session ID and socket and reports whether attachment succeeded. Ax and Claude must run under the same OS account. The session binding and optional child token stay in private host state, outside agent.ax.toml. Repeating setup from another session requires --takeover if the previous session is reachable, then changes the notification target without changing the agent identity. Running setup outside Claude retains an existing attachment and reports whether its endpoint is available.

Ax sends the attached conversation a notification containing the message ID and an ax messages fetch ID --workspace /path/to/workspace command. The notification omits the body; fetch reads the retained inbox message and marks it delivered, meaning picked up, not processed or completed. Repeat fetch returns the same retained message; it does not consume or delete it. ax messages inbox remains read-only. The receiving node commits acceptance before notifying the harness. An unregistered logical destination is held by that node; registration and attachment make its messages fetchable before setup returns.

Claude's inbound policy may hold or refuse a notification. Its existing action permissions remain in force. The optional child token delegates local session input to ax; it does not guarantee that Claude will accept a notification. A socket write alone leaves the message pending. The daemon wakes on message arrival, attachment and restart recovery; it does not repeatedly prompt an agent merely because pickup is absent. Ax does not launch/resume a harness or run an automatic reply loop. A repeated notification shows its attempt number and asks the agent to avoid repeating work. To retrieve a retained pending message, inspect the inbox and fetch its ID.

Several agents in one workspace

A host can register several named agents in the same working directory. Setup detects the harness where possible; --harness claude or --harness codex supplies it explicitly. Omit --name to use <directory>-<harness> for a new mailbox; existing matching identities retain their names. agent.ax.toml stores public identity references under [agents.NAME], with private keys outside the workspace.

Send, reply, inbox and fetch first honor --agent NAME, otherwise select the current attached session, a unique harness match, or the only workspace entry. Several matching agents require an explicit name. Moving or removing one agent preserves other workspace entries. For example:

ax agent setup --harness claude --workspace /absolute/project
ax agent setup --harness codex --workspace /absolute/project
ax send reviewer "Please review this change" --agent project-claude
ax messages inbox --agent project-codex

Which account runs commands

A user deployment runs the service and jobs as the SSH account. A system deployment runs the API as ax-service-user and uses a privileged helper to launch jobs as the selected non-root account. The job account defaults to the SSH user; system deployment can select another with --run-as.

Inspect the account and execution profile with:

ax exec info buildbox

The open profile inherits the job account's filesystem and network access. It is not a sandbox. A remote working directory chooses where the command starts; it does not restrict which other files that account can read or change.

Credentials and owner policy

The runner's local limits and the caller's effective authorization bound execution. Owner-written grants take precedence over scope-based authorization. Runner invites describes adding other identities and root-managed registration.

SSH deployment reports credential and issuer-delegation expiry times. Managed bootstrap credentials have finite lifetimes; redeployment refreshes them as described in the deployment reference. A root registration is a separate admission decision and can have no expiry.

Removing an SSH key or uninstalling ax does not revoke credentials or owner grants already issued. Handle revocation through the owner's enrollment and execution policy.

Harness labels

Harness, session and workspace fields help you identify where a job came from. They are caller-reported local history, not security identities or permission boundaries. See agent integration.

For the checks behind these boundaries, read the security model.