aster.ax / Docs

Security model

Ax gives an authorized client permission to run commands as a configured OS account. Its security depends on both the runner's access policy and that account's permissions. The open execution profile inherits the account's filesystem and network access; it is not a sandbox.

This document describes the current implementation. The privileged process controls below apply to Linux system installations. User installations have a different trust boundary, described separately.

Identity and permission are separate checks

Aster authenticates the connecting device using its node identity and checks whether it is admitted under the runner's trusted root. Knowing a runner's address or saving its name does not grant access.

Ax then checks permission for the requested execution operation. An owner-written Exec grant takes precedence. If the owner explicitly enables credential scopes, a caller without an owner-written grant can use the execution permissions in its verified credential or registration. Both paths are bounded by the runner's local policy, including enabled operations, execution profiles and limits.

Ax also checks who owns a job before allowing access to its status, output or cancellation. Another caller's permission to submit work does not automatically give it access to that job. Harness and session labels are bookkeeping supplied by the caller; they do not establish identity or grant permissions.

Revocation uses the owner's enrollment and execution records. A runner must receive a changed record before it can enforce that change. Removing an SSH key alone does not revoke an ax identity. See access and execution accounts and runner invites.

System installations separate privileged work from commands

A Linux system installation uses three roles:

Role OS permissions Responsibility
Network service Dedicated ax-service-user account Authenticate callers, check policy and handle requests.
Helper and job supervisor Root Create supervised jobs, apply their configured identity and manage their lifetime.
Job command Configured non-root account Run the requested executable and arguments.

The helper and supervisor are privileged, trusted parts of ax. The following controls keep their administrative permissions out of ordinary job commands:

Commands are submitted as an executable and argument list. Ax adds no implicit shell. A caller can explicitly request a shell when its execution policy permits it.

User installations trust the runner account

In user mode, the network service and job commands run as the same OS account. There is no privileged helper switching between accounts. An authorized command has that account's access, including access to its runner keys and state. Private file permissions protect against other accounts; they cannot isolate processes running as the same account.

Choose a dedicated runner account when work should have different permissions from your personal account. Inspect the selected account with ax exec info. See service installation for the two modes.

Sudo on Linux is an explicit owner choice

Jobs normally run with no_new_privs, which prevents gaining privileges through programs such as sudo. The owner can enable allow_sudo to permit the job account's existing sudo rights. Ax does not add sudoers permissions or supply a password.

If that account has unrestricted passwordless sudo, an authorized job can become root. This is administrative access deliberately enabled by the owner. See allow sudo in jobs.

macOS user jobs

Mac jobs use the same grant, caller and job-ownership checks. The supervisor and payload run as the installed user, with that account's normal OS permissions, including its ability to invoke sudo. Ax does not grant sudo access or provide passwords. Unlike Linux, this backend cannot enforce allow_sudo: false; an explicit false setting is rejected.

Each launchd supervisor outlives the API process and retains output and status. One lifetime helper per active job leads the payload process group. If the supervisor dies, the helper force-stops that group; if the helper dies, the supervisor stops the group and records lost supervision. Killing both AX processes simultaneously is outside this mechanism. Cancellation and deadlines signal the payload's process group. A command that moves descendants into a different session can escape that group. The reported capability is process_group_best_effort; it does not promise cgroup containment. Configured CPU, memory, process-count and file-size limits are rejected when the Mac backend cannot enforce them. The normal output-size limit still applies.

File transfers and resource limits

Receiving files requires both workspace-write permission and permission for the execution destination. The runner rejects destinations that overlap its private workspace state. The transfer implementation holds directory handles and checks file identities so that replacing a checked path with a symbolic link does not silently redirect writes to another location.

Execution requests, input, retained output and concurrent output watches have bounds. Job resource limits depend on the runner's configuration and backend. They do not reserve disk space for everything a command might create.

Receiver resource cleanup: ax retains at most 32 idle receiver objects in least-recently-used order. Each owns database connections; evicting an unused object releases those resources. Active transfers retain their receivers and do not count toward the idle allowance. A full idle cache does not refuse work.

Finished transfers are removed from the in-memory active map even if saving their outcome fails. Existing observers receive that failure; ax does not claim that a successful result was retained. Transferred files and durable operation records stay in place. This cleanup adds no concurrency limits, waiting queues, deadlines or cancellation requirements.

Verification and scope

Tests cover denied callers, job ownership, credential scopes, grant precedence, revocation and malformed requests. Linux-specific tests cover helper caller identity and dropping privileges before directory access. A privileged Linux run of those tests remains required to qualify system mode for release.

These controls do not contain a command that is deliberately given root access, or isolate an open job from other work under the same OS account. Protect the owner's keys and give runner accounts the OS permissions their work requires.