Artzi Download
Guides

Sharing teammates with your team

A team server lets other people on your team use agents that run on a computer you control. Each person signs in with their own account and uses only the agents they can access.

1. Sign in

Sign in with your email address. You receive a short code, and Artzi stores your session on this computer.

2. Publish this computer as a server

Open the server menu and choose to publish. The server stays online while this computer is on and Artzi is running.

3. Invite a teammate

Create an invitation and send the link. The person opens it, signs in and joins the server.

4. Choose who can use each agent

Set an access role for each agent. A teammate can only see and chat with the agents their role allows.

If you stop Artzi or turn the computer off, the server goes offline until you start it again.

Linux server

Download the Linux deb and its SHA256SUMS file into the same folder. Verify the package before installing:

sha256sum -c --ignore-missing SHA256SUMS && sudo apt install ./Artzi-<v>-amd64.deb

Then enable the user service:

loginctl enable-linger
systemctl --user enable --now artzi-server
artzi-server login you@example.com

Enter the sign-in code at the prompt. Check the server with artzi-server status, set its name with artzi-server name "Workstation", and sign out with artzi-server logout.

To install a later release, download its deb and checksum manifest into one folder, then run:

artzi-server upgrade ./Artzi-<v>-amd64.deb

The command verifies the published SHA-256 checksum, package name, architecture and version before installing. It reinstalls the same version or upgrades to a newer one; downgrades are refused because older versions may not be able to open newer data. The build signature is not checked yet.

An operator can also approve a release for staged updates through the existing client controls or CLI:

sudo /usr/sbin/artzi-server-update configure --user SERVICE_USER
systemctl --user daemon-reload
systemctl --user restart artzi-server
sudo /usr/sbin/artzi-server-update offer /private/releases/Artzi-<v>-amd64.deb --checksums /private/releases/SHA256SUMS
artzi-server update check --json
artzi-server update stage --json
artzi-server update status --json
artzi-server update apply --json

Poll until the stage is ready before applying. Apply waits for idle work; artzi-server update cancel cancels the wait. The separate coordinator verifies the stored package and preserves an interruption checkpoint outside the app installation. It resumes the same verified release after an interrupted install. Publisher signatures remain unchecked for unsigned builds. Enrollment covers the existing user unit and its private profile; close other desktop or unmanaged server processes before applying. For a custom profile, give its canonical path to configure --profile PATH and keep the unit aligned. Use /usr/sbin/artzi-server-update status and sudo /usr/sbin/artzi-server-update recover --retry for operator recovery when a partial install cannot run the app CLI.

To use your own account service, configure the user unit:

systemctl --user edit artzi-server

Add:

[Service]
Environment=ARTZI_ACCOUNT_API_URL=https://account.example.com

Then run systemctl --user daemon-reload and systemctl --user restart artzi-server. Sign out with artzi-server logout before switching between the default and a self-hosted account service. A signed-in server refuses to send its session to a different origin.

Agent display

Computer Use runs on a separate virtual display so screenshots and input do not reach the server's administration desktop. The deb recommends Xvfb, xauth, xdotool, x11-utils and ImageMagick. Check artzi-server status for the display number, dimensions and recovery guidance if its tools are missing.

Workspace-only agents on Linux require bubblewrap and user namespaces. If the sandbox check fails, Workspace-only refuses to start; artzi-server status shows the reason.

Uninstalling

Both sudo apt remove artzi and sudo apt purge artzi keep your user data:

  • ~/.config/Artzi stores sign-in, server identity and name, settings and chats.
  • ~/Artzi stores the workspace, unless ARTZI_HOME points elsewhere.
  • Your OS keyring keeps Artzi's storage key, which the saved sign-in needs.
  • Systemd user overrides and the enable link are retained.

Remove takes away the artzi command, the artzi-server wrapper and the system-wide unit. Purge also removes the AppArmor profile if one was installed. Neither deletes data under your home directory. To delete user data, first stop and disable the service, then remove ~/.config/Artzi, the workspace path (~/Artzi or ARTZI_HOME), any ~/.config/systemd/user/artzi-server.service.d override and ~/.config/systemd/user/default.target.wants/artzi-server.service; remove the Artzi account entry from your OS keyring separately.

Linux container

Build the Linux release and its local container image from a checkout:

bun install
bun run dist:linux
bun run container:build

container:build verifies the deb against dist/SHA256SUMS, checks its package name and architecture, and builds artzi-server:local. An explicit deb path can be passed after the command. The image build checks the checksum again before unpacking. Nothing is uploaded. Checksums establish that the image contains the selected artifact; signatures and registry provenance are not checked yet.

Create the keyring secret once, then start and claim the server:

(umask 077; test ! -e docker/keyring-password && openssl rand -hex 32 | tr -d '\n' > docker/keyring-password)
docker compose -f docker/compose.yaml up -d
docker compose -f docker/compose.yaml exec server artzi-server login you@example.com
docker compose -f docker/compose.yaml exec server artzi-server status --json
docker compose -f docker/compose.yaml exec server artzi-server name "Team server"

The code is entered at the prompt. A fresh headless server publishes automatically after sign-in. It connects out through the account service and relay, so the Compose file publishes no ports. To use your own infrastructure, add ARTZI_ACCOUNT_API_URL=https://account.example.com and ARTZI_SIGNAL_URL=wss://relay.example.com to the service's environment. Sign out before changing account services.

The named /data volume keeps settings, identity, encrypted credentials, keyring, provider homes and the workspace when a container is replaced. The image runs as user 1000:1000; a bind-mounted data directory must belong to that user. The keyring secret stays in a separate read-only mount. Keep a secure copy of both the data and the original secret: a different secret cannot unlock the saved keyring, and the server refuses to start with it. Anyone able to read both can unlock the credentials. Keep the secret out of repositories and backups that contain the data.

The runtime has a read-only root filesystem, no effective capabilities, no-new-privileges, a 512-process limit, 1 GiB shared memory and private temporary directories. Only SYS_CHROOT remains in the bounding set for Chromium's sandbox. The bundled seccomp policy allows user namespaces while retaining Docker's other syscall restrictions. The host must permit unprivileged user namespaces; startup refuses when they are blocked. Do not disable the Electron sandbox or the container's security policy.

Docker's default AppArmor policy prevents bubblewrap's nested mounts. Under that policy, status reports Workspace-only unavailable, and Workspace-only commands refuse to run. Full access commands run within the container. Computer Use has its own authenticated virtual display. Do not mount the Docker socket, a personal home directory or other host data into the server.

To replace the image, build the newer verified release, then run docker compose -f docker/compose.yaml up -d --force-recreate. Do not replace it with an older version: newer data may not open in older builds. Container updates replace the image; artzi-server upgrade is for systemd installations. docker compose down retains the data volume; down --volumes deletes it. The 60-second stop period lets Artzi stop agents and close its database, after which the runtime ends remaining processes.

Run bun run container:verify to check the image with disposable data, a local account service and relay, and a headless Chrome client. It checks unsafe startup refusal, claim, remote workspace access, recreation, crash recovery, secret retention and shutdown. The verified container target is Linux x64 with an Ubuntu 22.04 userspace and Docker. Other architectures, Podman, Kubernetes and rootless Docker are not checked yet.

Multiple Linux instances

The instance operator manages rootful Docker on the Ubuntu 22.04 x64 test target, using Docker's iptables firewall backend. Install Bun, Docker, systemd, iptables, util-linux and e2fsprogs, and build the local image above. From that checkout, install the operator and create an instance:

sudo "$(command -v bun)" scripts/linux-instances.ts setup
sudo artzi-instance create design --cpus 1 --memory 2g --disk 20g
sudo artzi-instance run design login you@example.com
sudo artzi-instance run design name "Design server"
sudo artzi-instance run design status --json
sudo artzi-instance list

Sign-in reads the code from stdin or a prompt that hides input. Each command requires the instance ID explicitly. IDs contain 1–24 lowercase letters, digits or hyphens and start with a letter or digit. CPU, memory and persistent disk quotas are mandatory; sizes use m, g or t (binary units). The image must already exist locally: create --image <tag-or-digest> pins its immutable image ID. Images are never pulled or published by the operator. The image label is checked; image signatures are not checked yet. Keep the pinned image available for recovery.

The default root is /srv/artzi, accessible only to root. Setup copies Bun, the operator, backup worker and container seccomp policy there, so boot and subsequent commands do not depend on the checkout. A custom installation uses a canonical absolute path with safe root-owned ancestors: sudo "$(command -v bun)" scripts/linux-instances.ts --root /srv/artzi-other setup --subnet 172.31.0.0/16. Use that installed root's .tools/bun .tools/operator.js --root /srv/artzi-other for later commands. The artzi-instance shortcut belongs to the default root.

Each instance has its own preallocated ext4 disk, data directory, keyring secret and container. Only its own data and read-only secret are mounted. The disk quota bounds persistent data; RAM also accounts for shared memory and temporary files. Docker logs rotate at 10 MiB with three files. The operator leaves at least 1 GiB free before reserving a disk. Backups, verification and retained recovery disks need additional host space. The same sandbox and Workspace-only limitation described above applies to every instance.

The default network is 172.30.0.0/16; setup rejects overlap with existing Docker networks. A different private /16–/28 subnet can be supplied with --subnet. Instances have no published ports, cannot connect to one another or host services, and cannot reach private, loopback, link-local, metadata, benchmark or multicast destinations. IPv6 is disabled and blocked at the bridge. Public egress and Docker DNS remain available. Repeat --deny <IPv4-CIDR> at setup to block additional destinations. Private account/relay services are therefore outside this deployment profile; use public HTTPS/WSS endpoints, with both --account-url and --relay-url on create, when using your own services.

Setup installs a scoped firewall unit before Docker and persistent loop mounts before container startup. If isolation rules are absent, up refuses. A missing data mount remains owned by root and unwritable, so the server refuses to create an empty replacement profile. Rootless Docker, user namespace remapping, other firewall backends and other container engines are not checked yet. The host and its root/Docker administrators remain trusted.

Instance backups and recovery

Create a backup and use the exact backup ID printed by that command:

sudo artzi-instance backup design
sudo artzi-instance verify design 20261028T120000Z-aabbccdd
sudo artzi-instance restore design 20261028T120000Z-aabbccdd --confirm design
sudo artzi-instance status design

Backup briefly stops the target container and all its processes, copies its complete data (including SQLite WAL files), then restarts it if it was running. The bundle contains manifest.json, data.tar.gz and SHA256SUMS. Before publishing it under /srv/artzi/backups/<instance>/<backup-id>, the operator extracts it onto a separate quota-bounded disk, checks every path, type, mode and file checksum, and runs SQLite quick_check. Archive and database processing run as an unprivileged user in a constrained container with no network. No tenant archive is extracted by root.

Restore repeats those checks while the current instance remains available. It requires the same instance ID, original keyring secret, pinned image and application version, and a disk at least as large as the backup's quota. A failed verification leaves the current disk selected and running. After verification, restore stops the target, switches its disk pointer atomically and starts it again if it was running. Startup failure selects the previous disk again. A crash during the switch leaves a pointer to either the previous disk or the fully verified recovery disk. Other instances are not stopped or changed. Only one operator mutation runs at a time per root; overlapping commands fail instead of queuing a destructive action.

Backups contain private workspace and account data. They are checksummed, not signed or encrypted; store exported copies in protected storage. Keep a separate secure copy of each instance's original /srv/artzi/instances/<instance>/keyring-password. Its fingerprint is in the manifest; the secret itself is never included. Losing it prevents credential recovery. For recovery on a new host, load the exact pinned image, set up the operator, create the same ID and quotas with --secret-file /root/original-keyring-password (a private root-owned file), copy the root-owned backup bundle into the same backups/<instance>/<backup-id> layout, and run verify followed by restore. Changing the instance ID or using a different build is deliberately rejected.

Successful restores retain the previous disk. After checking recovery, explicitly reclaim old disks and incomplete backups with sudo artzi-instance prune design --confirm design. status lists backup IDs, old disks and incomplete backups, and reports a missing or changed secret. Completed backups are never pruned automatically. stop design and up design control the runtime. To delete an instance, use sudo artzi-instance remove design --confirm design; this deletes its disks and secret, retaining its backup bundles. Save the original secret separately first. teardown --confirm /srv/artzi removes the scoped network and boot configuration only after all instances have been removed.

Run sudo "$(command -v bun)" scripts/smoke-linux-instances.ts in a disposable Ubuntu VM to exercise two tenants, real resource limits and disk exhaustion, denied network access, SQLite WAL recovery, corrupt backup refusal, explicit confirmation, restore, pruning and removal. The smoke creates and removes its own data root, containers, network and firewall rules.

Own account, relay and TURN services

Use bun run services prepare for the account/site services and bun run stack prepare for Signal and TURN. The tools validate private credentials, certificates, routing and matching keys. The service operations runbook covers preparation, the disposable rehearsal, rotation and the integrations that need separate operator registrations. Real domains, certificates, Cloudflare resources and SMTP credentials are operator inputs. Sign out before changing services, then configure both ARTZI_ACCOUNT_API_URL and ARTZI_SIGNAL_URL for the installed client or server.

Hosted servers

Desktop Settings → General and web Settings list the hosted servers your account owns. Inspect shows the desired state and last account observation. Wake and Retry work while a server is offline. Provider delays show the next attempt; exhausted failures can be retried on the same server.

Delete server requires typing the exact server name. Access ends immediately, while Deleting remains visible until cleanup finishes. If a request fails, refresh the list before trying again. Creation is available only when the service operator has configured hosting; the default service has no provider.

All guides