Documentation Index
Fetch the complete documentation index at: https://docs.awaithumans.dev/llms.txt
Use this file to discover all available pages before exploring further.
awaithumans is designed to be self-hostable in one command. The reference Docker Compose file boots:
- The awaithumans server (with bundled dashboard)
- Postgres for task storage
- Health-check endpoints
Once up, point your DNS at the host. Done.
docker-compose.yml
services:
server:
image: ghcr.io/awaithumans/awaithumans:latest
ports:
- "3001:3001"
environment:
AWAITHUMANS_PUBLIC_URL: https://reviews.your-company.com
AWAITHUMANS_DATABASE_URL: postgresql://awaithumans:${POSTGRES_PASSWORD}@db:5432/awaithumans
AWAITHUMANS_PAYLOAD_KEY: ${PAYLOAD_KEY}
AWAITHUMANS_ADMIN_API_TOKEN: ${ADMIN_API_TOKEN}
AWAITHUMANS_ENVIRONMENT: production
# Slack (static-token mode shown — see /channels/slack for OAuth)
AWAITHUMANS_SLACK_BOT_TOKEN: ${SLACK_BOT_TOKEN}
AWAITHUMANS_SLACK_SIGNING_SECRET: ${SLACK_SIGNING_SECRET}
# Email (Resend transport shown — see /channels/email for SMTP)
AWAITHUMANS_EMAIL_TRANSPORT: resend
AWAITHUMANS_EMAIL_FROM: notifications@your-company.com
AWAITHUMANS_EMAIL_FROM_NAME: "Acme Reviews"
AWAITHUMANS_RESEND_KEY: ${RESEND_KEY}
# Verifier (optional)
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
# Dashboard CORS — locked to your operator's domain
AWAITHUMANS_CORS_ORIGINS: https://reviews.your-company.com
depends_on:
db:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"]
interval: 30s
timeout: 5s
retries: 3
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: awaithumans
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: awaithumans
volumes:
- awaithumans-data:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U awaithumans"]
interval: 10s
timeout: 5s
retries: 5
volumes:
awaithumans-data:
.env file
Compose interpolates ${VAR} from a .env file next to docker-compose.yml. Drop this template in beside it and fill in each value before you docker compose up:
# .env (sit beside docker-compose.yml)
# === Secrets you generate yourself (see "Generate the secrets" below) ===
PAYLOAD_KEY=replace-me-with-a-fresh-32-byte-urlsafe-string
ADMIN_API_TOKEN=replace-me-with-a-fresh-32-byte-urlsafe-string
POSTGRES_PASSWORD=replace-me-with-a-strong-db-password
# === Slack channel (optional — leave blank to disable) ===
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...
# === Email channel — Resend (optional — leave blank to disable) ===
RESEND_KEY=re_...
# === AI verifier (optional — only the providers you use) ===
ANTHROPIC_API_KEY=sk-ant-...
Add .env to .gitignore. Production deployments should pull these from your secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager) rather than a flat file.
Generate the secrets
PAYLOAD_KEY (the encryption root), ADMIN_API_TOKEN (the bearer token your agent uses), and POSTGRES_PASSWORD are the three secrets you set yourself.
python -c 'import secrets; print(secrets.token_urlsafe(32))'
# tlR5UCElY4QIjThpO4TlL1GzTzXrQQJYa3BtvZ0FOBQ ← PAYLOAD_KEY
python -c 'import secrets; print(secrets.token_urlsafe(32))'
# YrKxVj9FOaEP2UnVQWf1kT87Ld6sPmA9XgB3ZNzuIqs ← ADMIN_API_TOKEN
python -c 'import secrets; print(secrets.token_urlsafe(24))'
# 9k4-ZmHFlS3sLNyq4mUgQAxRpO72j8wB ← POSTGRES_PASSWORD
Paste each into .env. Both PAYLOAD_KEY and ADMIN_API_TOKEN must NEVER be regenerated after first deploy:
- Rotating
PAYLOAD_KEY invalidates every session cookie + magic-link token + encrypted Slack OAuth row.
- Rotating
ADMIN_API_TOKEN breaks every running agent until you redeploy them with the new value.
If you must rotate, do it during a planned maintenance window with a coordinated redeploy.
First-run setup
On first boot the server detects an empty users table and prints a one-shot setup URL to the logs:
✓ Open the dashboard at:
https://reviews.your-company.com/setup?token=<32-byte-token>
(one-shot setup link — paste into your browser)
Open it within an hour, create your operator account. After that, the URL is dead — subsequent setups require an admin to add users via the dashboard.
For automation: hit POST /api/setup/operator with the token + operator credentials in JSON. See /api/overview.
TLS / HTTPS
Production REQUIRES HTTPS (AWAITHUMANS_PUBLIC_URL starting with https://):
- Slack OAuth tokens transit via redirect URLs
- Session cookies are
Secure flagged when PUBLIC_URL is HTTPS
- Magic-link tokens go in URLs that mail clients log
The recommended pattern is a reverse proxy (Caddy / nginx / traefik) terminating TLS in front of the awaithumans container. Caddy example:
reviews.your-company.com {
reverse_proxy server:3001
}
Backups
Two things matter:
- Postgres data volume (
awaithumans-data) — daily snapshot is enough; an hour of lost task data is acceptable for most teams.
- PAYLOAD_KEY — without it, encrypted Slack OAuth rows can’t be decrypted. Store it alongside your other root secrets (1Password, Vault, AWS Secrets Manager).
The dashboard build is bundled into the server image; nothing to back up there.
Scaling
The single-process design works up to ~10k tasks per hour without tuning. Beyond that:
- Run multiple
server replicas behind a load balancer
- Use
PgBouncer if you hit Postgres connection limits
- Move the timeout scheduler to a single-leader pattern (currently it runs in every replica — fine at low scale, wasteful at high)
Multi-replica deployments are a documented post-launch hardening pass. For v0.1, single replica is the supported config.
Health check
GET /api/health → {"ok": true, "version": "0.1.0", "db": "connected"}
Wire it to your orchestrator. The endpoint is unauthenticated (it has to be, for healthchecks).
Logs
Structured JSON to stdout. Each log line carries:
timestamp (ISO8601)
level
logger (e.g. awaithumans.server.routes.tasks)
message
request_id (correlated across the lifetime of one HTTP request)
Pipe to your aggregator of choice. The root logger has a built-in scrubber that redacts API keys, bearer tokens, password fields, and admin-token headers — even if upstream code accidentally logs them. See Configuration.