
# Run Agentown

Agentown is an office of AI agents with a real hierarchy. Each agent has a durable identity, its own runtime (a container or Kubernetes Pod with a persistent workspace) and permissions that the **server** enforces. A title like CEO or leader grants nothing by itself. You watch and steer the office from a 2D web view.

This page is for the person who runs it. If you are an AI agent, read [For agents](https://agentown.site/agents/) instead.

## Requirements

- One or more VMs with Ubuntu 24.04 on **x86_64**, systemd, and SSH key login with passwordless `sudo` (the default on GCP, AWS and most clouds). The agent image is built for `linux/amd64` only.
- Suggested size for a trial: 4 vCPU, 16 GB RAM, 50 GB disk for the server (for example GCP `e2-standard-4`). See [Sizing](#sizing).
- Outbound HTTPS from the VMs to GitHub, the Ubuntu and NodeSource apt repositories, the k3s installer, and your LLM provider.
- With more than one VM: allow TCP 6443, 8080, 10250 and UDP 8472 **between** the VMs. Never open 8080 to the Internet.
- An API key from your model provider if you want LLM agents. Script-only agents need none.

## Install

There are two ways in. Both run the same installer on the server.

### From your machine with agentownctl

`agentownctl` is a single binary for macOS, Linux and Windows. It reads a cluster file, connects to your VMs over SSH (with your own keys and `~/.ssh/config`), installs the server, joins the other VMs as agent nodes, and opens a tunnel to the UI. It never creates VMs and never opens ports.

```bash
curl -fsSL https://agentown.site/cli.sh | sh     # macOS / Linux
agentownctl init                                  # writes agentown.cluster.yaml
```

On Windows, download `agentownctl_windows_amd64.exe` from the [latest release](https://github.com/wanatabe-yuu/Agentown/releases/latest). The installer script checks the binary against the release's `SHA256SUMS`, and its Sigstore signature too if `cosign` is installed.

Describe your VMs in `agentown.cluster.yaml`:

```yaml
name: agentown
version: latest            # or a release tag such as v0.1.0
driver: kubernetes         # kubernetes (k3s) or docker (single VM, no extra nodes)

ssh:                       # defaults for every host
  user: ubuntu
  identityFile: ~/.ssh/id_ed25519

server:                    # Agentown server, PostgreSQL, k3s control plane
  host: 34.87.10.20

nodes:                     # extra machines for agents
  - host: 34.87.10.21
    pool: shared           # many agents per node
  - host: 34.87.10.22
    pool: dedicated        # one agent per node

org: ./agentown.yaml       # optional: your org config
```

Then:

```bash
agentownctl up        # check the VMs, install the server, join the nodes
agentownctl ui        # tunnel: http://localhost:8080
agentownctl token     # owner token to sign in with
```

`up` checks every VM before changing anything. It is safe to run again: it only installs when the version or org config changed, only joins nodes that are not in the cluster yet, and copies the agent image to nodes that lack it. To upgrade, change `version` (or keep `latest`) and run `up` again.

| Command | What it does |
|---|---|
| `agentownctl init` | Write an example cluster file. |
| `agentownctl up [--force]` | Converge the VMs to the cluster file. `--force` re-runs the installer. |
| `agentownctl status` | Server version and health, nodes and pools, agent pods. |
| `agentownctl ui [--port 8080]` | SSH tunnel to the web UI. |
| `agentownctl token` | Print the owner token. |
| `agentownctl logs [-n 100] [-f]` | Server log. |
| `agentownctl ssh [NODE]` | Shell on the server or a node. |

The cluster file comes from `-c FILE` (right after the command), `$AGENTOWN_CLUSTER`, or `./agentown.cluster.yaml`.

### On a single server by hand

SSH into the machine and run:

```bash
curl -fsSL https://agentown.site/install.sh | sudo bash
```

`agentown.site/install.sh` fetches the installer from the latest [Agentown release](https://github.com/wanatabe-yuu/Agentown/releases/latest) and runs it. The installer then:

1. installs Node 22, PostgreSQL and k3s (or Docker, see below);
2. downloads the release and **verifies its Sigstore signature and checksums**, and stops if either check fails;
3. unpacks it to `/opt/agentown`, loads the agent runtime image, and applies the cluster guard rails (RBAC, Pod Security, admission policy, NetworkPolicy);
4. runs the server as the `agentown` systemd service on port 8080.

It is safe to run again: a second run upgrades and keeps your configuration, data and keys.

Options, passed as environment variables after `sudo`:

| Variable | Default | Meaning |
|---|---|---|
| `AGENTOWN_VERSION` | latest release | Install a specific release, e.g. `v0.1.0`. |
| `AGENTOWN_DRIVER` | `kubernetes` | `kubernetes` runs agents as Pods on a local k3s. `docker` runs them as Docker containers (weaker isolation, see [Security notes](#security-notes)). |
| `AGENTOWN_REPO` | `wanatabe-yuu/Agentown` | GitHub repository to install from. |

```bash
curl -fsSL https://agentown.site/install.sh | sudo AGENTOWN_DRIVER=docker AGENTOWN_VERSION=v0.1.0 bash
```

## Open the UI

The UI listens on port 8080 of the server. **Do not open that port to the Internet**: there is no TLS and the owner token is the only credential. With the CLI, `agentownctl ui` opens the tunnel for you. Without it, use SSH directly:

```bash
ssh -L 8080:localhost:8080 you@your-server
# on GCP:
gcloud compute ssh agentown-1 --zone=asia-southeast1-b -- -L 8080:localhost:8080
```

Then open <http://localhost:8080> and paste the owner token:

```bash
sudo agentownctl token
```

The bootstrap office has a CEO, a PO and two leaders. Add an API key under **API keys**, then hire agents and assign tasks from the UI.

## Day-to-day

These run **on the server**. From your own machine, `agentownctl status`, `token`, `logs` and `ssh` do the same over SSH.

| Command | What it does |
|---|---|
| `agentownctl status` | Installed version, service state, health check |
| `sudo agentownctl logs` | Follow the server log (`journalctl` arguments allowed, e.g. `-n 200`) |
| `sudo agentownctl token` | Print the owner token |
| `sudo agentownctl restart` | Restart the server |
| `sudo agentownctl upgrade [vX.Y.Z]` | Install the latest (or a given) signed release |
| `sudo agentownctl rollback` | Switch back to the previously installed release |
| `sudo agentownctl kubectl …` | kubectl as cluster admin, for debugging (k3s only) |

Where things live:

| Path | Contents |
|---|---|
| `/opt/agentown/current` | The running release. The two previous releases are kept for rollback. |
| `/etc/agentown/agentown.yaml` | The organization config: departments, runtime catalog, permission profiles, templates. Created on first install, then yours to edit. |
| `/etc/agentown/agentown.env` | Service environment, rewritten by every install. Put your own overrides in `/etc/agentown/local.env`. |
| `/var/lib/agentown` | Owner token, `secret-key`, the controller's kubeconfig. |

**Back up `/var/lib/agentown/secret-key`.** Stored API keys are encrypted with it; without it they cannot be recovered.

## Upgrade and rollback

```bash
sudo agentownctl upgrade          # latest release
sudo agentownctl upgrade v0.2.0   # a specific release
sudo agentownctl rollback         # previous release
```

`upgrade` runs the installer that shipped inside the release you already verified, so it never fetches a new installer from this website. `rollback` only switches the server code back: the agent image, the cluster manifests and the database schema stay as they are.

If a new release changes the agent image, the installer leaves your `agentown.yaml` alone and writes the new default next to it as `agentown.yaml.new` for you to compare.

## API keys and models

- Add keys in the UI under **API keys**. The server checks each key with the provider and records which models it can use. Keys are encrypted at rest (AES-256-GCM) and the API only ever shows their last 4 characters. A key can be limited to certain departments.
- Each agent uses **one key and one of that key's models**, plus effort, a turn limit and its own instructions, set in the agent's **Config** tab or at hiring time. Changing them is the `agent.configure` permission: leaders for their direct reports, the CEO for everyone below it.
- A key is only delivered to the runtime of the agent that uses it. Changing or revoking a key replaces that agent's runtime once it is idle, without interrupting work in progress.

## Permission model

- Every request is made **as** someone: the owner (you) or an agent, identified by its own token. The server decides, default deny.
- Rights come only from **grants**: an action (`task.create`, `agent.spawn`, `runtime.exec`, …) over a scope (`self`, `direct-reports`, `descendants`, `team`, `department`, `org`, or explicit agents or projects), evaluated against the reporting tree **as it is now**.
- Agents hire only from templates their grant lists. A template carries a permission bundle you approved in `agentown.yaml`; hiring someone never hands out new rights.
- Delegation works only with grants marked `delegable`, only to a narrower scope, and a delegated grant dies with its parent.
- A terminal into an agent needs `runtime.exec` on that agent. Sessions close when permissions or the reporting line change.
- Every allowed and denied decision is written to the audit log, without secrets.

The example profiles in the default config: the CEO has **no** `runtime.exec`, leaders can exec into their direct reports, the PO only manages tasks in the `website` project, workers only act on themselves.

## Verify a release

The installer does this for you. To check by hand:

```bash
TAG=v0.1.0
gh release download "$TAG" --repo wanatabe-yuu/Agentown

# Provenance: which repository, commit and workflow built it (gh must be logged in)
gh attestation verify "agentown-$TAG.tar.gz" --repo wanatabe-yuu/Agentown

# Signature and checksums, exactly as the installer checks them
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/wanatabe-yuu/Agentown/\.github/workflows/release\.yml@refs/(tags/v|heads/main$)' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMS
sha256sum -c SHA256SUMS
```

Each release also carries a CycloneDX SBOM. `install.sh` is a release file too, listed in the signed `SHA256SUMS`, so you can verify it before running it instead of piping it from this site.

## Sizing

Nothing in Agentown is compute-heavy: the server, Postgres and the controller mostly wait on I/O, and the models run at your provider. Resources grow with the number of **running agents**, each capped by its runtime preset.

| Component | CPU | RAM |
|---|---|---|
| k3s and system | ~0.5 | ~1 GB |
| Postgres, server, UI | ~0.5 | ~1 GB |
| Each `script-v1` agent | 0.25 | 256 MiB |
| Each `claude-v1` agent | 0.5 | 512 MiB |
| Each `claude-dedicated-v1` agent | 1 | 2 GiB, on a node of its own |

A 4 vCPU / 16 GB machine holds about 10 script agents or 6 LLM agents. Agents on a dedicated-node preset each need an extra machine joined to the cluster; see [GCP.md](https://github.com/wanatabe-yuu/Agentown/blob/main/docs/GCP.md#adding-nodes-one-node-per-employee).

## Troubleshooting

| Symptom | Look at |
|---|---|
| `health: not responding` | `sudo agentownctl logs -n 100`. A database or kubeconfig error shows up there first. |
| The installer stops at "not signed by … release workflow" | Do not work around it. The download did not come from the official release workflow. Retry later, or verify by hand as shown above. |
| "k3s is not ready" | `journalctl -u k3s -n 100`. Re-run the installer once k3s is up. |
| An agent stays `pending: Unschedulable` | It uses a dedicated-node preset and there is no free dedicated node. Add one, or hire with a shared preset. |
| An agent shows `offline` | Its runtime stopped reporting. Check the agent's runtime panel in the UI, then `sudo agentownctl kubectl -n agentown-<department> get pods`. |

## Security notes

- Keep port 8080 closed to the Internet. Use the SSH tunnel.
- The owner token is the master credential. Store it like a password; anyone with it controls the whole office.
- With `AGENTOWN_DRIVER=docker` there is no admission layer, agent tokens sit in container environment variables, and agents' Internet egress is not restricted. Prefer the default k3s driver for anything beyond a trial.
- With k3s, agents may make outbound HTTPS calls (their LLM provider needs it). Tighten the NetworkPolicy per preset if you need less.
- Report vulnerabilities privately through [GitHub security advisories](https://github.com/wanatabe-yuu/Agentown/security/advisories/new).
