Files
clawmates/deploy/compose
Omar SobhandClaude Opus 5 76ac3714f1
deploy / test (push) Successful in 5m15s
deploy / build (push) Successful in 5m28s
sec(door): closed by default, governor fails closed; self-authoring off by default
Three fail-open paths on the §15 door: no env at all meant allow-all; a
governor that could not be reached approved with a WARNING; and a reply
that never said DENY — empty, truncated, a refusal — approved, because the
rule was !contains("DENY"). On the two days the judge plan emptied every
outbound action was approved by nobody.

Now: governor_allows() needs an explicit ALLOW and no DENY; both judge()
implementations return false when unreachable; with no governor the door
opens only on CLAWMATES_DOOR_POLICY=allow. Open Agent Passport (arXiv
2603.20953): 74.6% social-engineering success under a permissive policy,
0 of 879 under a restrictive one. Local override gains the governor prod
already runs.

skill_self_authoring: default flipped to OFF. No agent-authored skill has
ever been delivered to a mission or scored; prod held zero proposals.
Enable with CLAWMATES_SKILL_SELF_AUTHORING=1 once promoted skills go
through the files arm and get a Skill-Use score.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WZb5A2kfVfjpdwSochkuHz
2026-09-20 22:07:39 -05:00
..

Clawmates on Docker Compose

A single-node deployment of the whole platform — the same images the Kubernetes/Helm path uses, with the same §15 security topology. This is the air-gapped appliance route; it is equally usable as a simple self-host.

What runs

Service Role
postgres database (named volume pgdata)
broker the secret broker — credentials never leave it; reachable only over a private socket volume shared with the server
socket-proxy allow-listed Docker API so the server can spawn agent sandboxes and nothing else
server API + streaming gateway + agent runtime + scheduler
frontend the Next.js web app

Networks core, secrets_net, sandbox_net, and engine_net are all internal: true; only edge is published. Agent sandboxes run with no network at all (egress is the browser container's alone).

Quick start

cd deploy/compose
cp .env.example .env
# Edit .env: set POSTGRES_PASSWORD and CLAWMATES_BOOTSTRAP_OWNER_PASSWORD.

# Either build the images locally...
docker compose build
# ...or load them from a signed release bundle (see deploy/airgapped/install.sh).

docker compose up -d

The server self-migrates on boot and, if CLAWMATES_BOOTSTRAP_OWNER_PASSWORD is set, provisions the first Owner + workspace once (a no-op on every later boot). Then open:

Configuration

Host- and secret-specific values come from .env (overlaid onto clawmates.toml at runtime — CLAWMATES_* env always wins). The knobs:

Concern Where Notes
DB password .env POSTGRES_PASSWORD also forms the server/broker DSN
Image tag .env CLAWMATES_VERSION latest after a local build, or a release version
First owner .env CLAWMATES_BOOTSTRAP_* password set = bootstrap on first boot
LLM clawmates.toml [llm] openai_compat (default, point base_url at vLLM/Ollama/llama.cpp) or anthropic (+ ANTHROPIC_API_KEY in .env)
Auth clawmates.toml [auth] + .env AUTH_MODE local (default) or clerk (see docs/clerk.md)
Tracing .env CLAWMATES_TELEMETRY__OTLP_ENDPOINT unset = logs only, no egress

Using Anthropic instead of a local model

In clawmates.toml:

[llm]
provider = "anthropic"
model = "claude-sonnet-4-6"

and set ANTHROPIC_API_KEY in .env.

The broker master key — back it up

On first boot the broker generates its encryption key into the broker_key volume and logs a reminder. Every stored credential is unrecoverable without it. Back it up:

docker compose cp broker:/etc/clawmates-broker/broker.key ./broker.key.backup

Operations

docker compose ps                 # status
docker compose logs -f server     # follow server logs
docker compose pull && docker compose up -d   # upgrade to a new CLAWMATES_VERSION
docker compose down               # stop (keeps volumes/data)
docker compose down -v            # stop AND delete all data

Production notes

  • Put a TLS-terminating reverse proxy in front of ports 3000/8080; the SSE gateway needs response buffering off (the Helm ingress sets this; nginx: proxy_buffering off; with long read timeouts).
  • socket-proxy mounts the Docker socket read-only and exposes only the container lifecycle verbs — verified by crates/cm-sandbox/tests/socket_proxy.rs.
  • The full bring-up is exercised end to end by scripts/rehearse-install.sh (verify a signed bundle → docker loadcompose up → assert the login page serves), which also runs in the release pipeline.