Cloud worker environment keys under cloudWorkers.*.

For the full key index and the other top-level config domains, see Configuration reference.

Cloud worker environments

Cloud workers are opt-in. If cloudWorkers is absent, or profiles is empty, Apus accepts no new cloud-worker creation and does not advertise a Cloud destination. sessions.dispatch may remain available for eligible paired-device targets. The config schema and read-only environments.list and environments.status methods remain available. Durable records created earlier still reconcile and remain visible; the existing gateway/node projection is unchanged.

SSH-backed remote-exec providers must return a trusted hostKey as exactly algorithm base64, without a hostname or comment. Bootstrap writes that key to an isolated known_hosts file, uses StrictHostKeyChecking=yes, and fails before opening a connection when the provider omits it. There is no trust-on-first-use fallback. These providers also carry workspace traffic over separate pinned SSH connections so rsync cannot block control traffic.

Node-backed providers return an authenticated node device id for either worker-turn or remote-exec. The Gateway installs the current pinned bundle and transfers the workspace through the node transport; these leases do not return or resolve Apus SSH endpoint credentials. worker-turn requires a node lease and launches a restricted Apus worker child. remote-exec can use either an enrolled node or an existing SSH-backed provider and keeps the harness plus model authentication on the Gateway.

Crabbox profile

In Settings → Connections → Cloud workers, the profile editor's Advanced group edits warm images, setup environment names, ready workers, and suspend-after duration. The page also exposes the shared Prepared pool cap. Clearing optional values restores their defaults; selecting Auto for warm images restores automatic selection. Changes apply without restarting the Gateway. To prepare an image after saving a profile, use Snapshots → Build snapshot. Saving does not start a build.

Snapshot retention is plugin-wide, separate from profile settings. Configure plugins.entries.crabbox.config.warmImages.refreshAfter (default 24h, minimum 1h), retainUnused (default 14d, minimum 1d), and keepPrevious (0 or 1, default 0) in the Snapshots → Retention policy card or config. Durations accept whole minutes, hours, or days. Changes reload the Crabbox plugin without restarting the Gateway. See Retention policy for the complete syntax, pinned exemptions, and previous-generation behavior.

The bundled crabbox provider provisions a disposable machine through the local Crabbox CLI, enrolls it as an ephemeral outbound node, and returns the same node transport for Apus worker-turn or Codex remote-exec. One configured profile can therefore be selected by both harnesses; the selected session runtime determines its execution semantics. The inner settings.provider selects the Crabbox backend; it is separate from the outer Apus provider id.

{
  gateway: {
    nodes: {
      commands: {
        // Required only when this profile also runs Codex remote-exec sessions.
        allow: ["codex.exec-server.stdio.v1"],
      },
    },
  },
  cloudWorkers: {
    preparedPool: { maxTotal: 4 },
    profiles: {
      production: {
        provider: "crabbox",
        suspendAfter: "45m",
        readyWorkers: 1,
        settings: {
          provider: "aws",
          class: "standard",
          ttl: "24h",
          idleTimeout: "60m",
          // Optional preferred executable. Apus manages a current copy when needed.
          binary: "/usr/local/bin/crabbox",
        },
      },
    },
  },
}

Managed release archives stream into private staging files, bounded to 128 MiB, before checksum verification and extraction. Download progress has a 30-second idle limit and a separate ten-minute total limit; failed downloads are cleaned up before acquisition returns.

The supported CLI is also required to inspect and stop existing leases. On hosts with restricted release-download access or managed-tool write permissions, provision the supported executable at the exact path used by existing profiles, or stage the managed distribution before rolling out an Apus update. Supported executables and installed managed copies do not need release-download access. If neither is available, acquisition must succeed before lease inspection or teardown can continue; teardown stops heartbeats before attempting acquisition.

Unknown settings are rejected. Crabbox credentials and backend-specific account configuration remain owned by Crabbox; do not place them in settings. Apus invokes only the local CLI and makes no provider network calls from this plugin. Provisioning passes one deterministic canonical lease ID through --lease-id, keeps --slug as display metadata only, and always passes --keep=true; Apus owns the external lifecycle and destroys the lease with crabbox stop --id <canonical-id>. After an ambiguous result, Gateway reconciliation repeats the same fixed-ID operation. Crabbox must return the exactly attested lease or fail closed; Apus never falls back to slug adoption or replacement allocation.

Provider support and backend-specific setup belong to Crabbox. Configure credentials, coordinator access, networking, and snapshots there rather than duplicating them in Apus settings. The installed backend must satisfy Apus's cloud-worker lifecycle requirements.

Crabbox setup uses an environment-owned one-use pairing credential and the configured public Gateway URL. The provider returns the exact authenticated node id; the Gateway then installs its current bundle and transfers the workspace through authenticated node routes. For Codex remote execution, Crabbox prepares the bundled Codex plugin and pinned managed binary in the node's private state, and the Gateway requires the explicitly allowed codex.exec-server.stdio.v1 command plus critical allow-once approval for each attempt. No Apus worker child or worker slot is used in that mode. Apus does not persist Crabbox SSH endpoint, key, host-key, or fallback-port output.

AWS admission requires providerMetadata.instanceProfileAttached to be false.

Static SSH development profile

{
  cloudWorkers: {
    profiles: {
      development: {
        provider: "static-ssh",
        settings: {
          host: "worker.example.test",
          port: 22,
          user: "apus",
          hostKey: "ssh-ed25519 <base64-public-host-key>",
          keyRef: {
            source: "env",
            provider: "default",
            id: "APUS_WORKER_SSH_KEY",
          },
        },
      },
    },
  },
}

A supported Node runtime (24.22.1+ or 26.12.1+) with WAL-reset-safe SQLite must already be installed on the worker. The opt-in "npm" method also requires npm and outbound HTTPS access to the public npm registry. Networked toolchain setup is provider policy; bootstrap reports an actionable error instead of installing toolchains itself.

Node-backed worker-turn launches the self-contained worker loop and proxies model inference through the Gateway. Node-backed or SSH-backed remote-exec keeps the model loop on the Gateway and routes sandbox operations to the remote host. Node-backed Codex accepts process, filesystem, capability, and credential-free HTTP operations; authenticated HTTP is rejected before reaching the node. Both modes reconcile the session workspace and transcript through the durable placement lifecycle. A disconnected node-backed Codex attempt is terminal; reconnect permits only a fresh attempt, never process or stream resumption.

Each durable environment record retains its validated provider settings and resolved install method in a creation-time profile snapshot. Changing or removing a named profile affects new creates; existing records continue lifecycle reconciliation with that snapshot, provided the owning plugin remains available.

With the default gateway.reload.mode: "hybrid", profile and pool changes apply without restarting the Gateway. New allocations use the updated profile; existing allocations keep their admitted provider settings. Unused reserves are checked against the current profile and pool limits, and incompatible or excess workers retire after their provider work settles. Suspend-after changes apply to existing idle sessions before their next automatic drain. With reload mode "off", restart the Gateway to load configuration changes.

The static-ssh provider is a source-tree QA Lab remote-exec harness and is excluded from packaged distributions. A worker running on its shared host can read unrelated host data, so do not use this provider as a production isolation boundary. Its operator must supply the expected hostKey; Apus will not learn or accept a key from the first connection. Destroying its lease only releases Apus's logical record; it does not stop or clean the host.