Documentation menu

Operating a hub

For the people who run a hub: the official hub, or a self-hosted one. The hub is a Next.js app with a Postgres database, in hub/ of the repository.

Configuration#

Variable Required Meaning
HUB_ENV Yes development, test, or production. Outside production the hub only accepts the databases agentwarden_hub_dev and agentwarden_hub_test.
HUB_PUBLIC_URL Yes The address sites and people use, for example https://hub.agentwarden.com.
DATABASE_URL Yes postgres:// URL.
HUB_SIGNING_KEY Yes 64 hex characters from npx tsx bin/keygen.ts, which also prints the public key. Keep it secret.
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY With more than one instance A stable base64 key shared by every instance.
HUB_MAIL_MOCK, HUB_SMTP_URL, HUB_MAIL_FROM For real email Mail goes to the outbox table unless HUB_MAIL_MOCK=0 and both SMTP settings are set.
DODO_MOCK, DODO_API_KEY, DODO_WEBHOOK_SECRET, DODO_ENVIRONMENT, DODO_PRODUCT_AGENCY_<25|UNLIMITED>_<MONTHLY|ANNUAL>, DODO_PRODUCT_PRO_<MONTHLY|ANNUAL> For billing and Pro licenses Billing is mocked unless DODO_MOCK=0 with the key, the webhook secret, and at least one Agency product. Pro license checks are mocked until a Pro product is set with DODO_MOCK=0. Production refuses both mocks. Point Dodo's webhook at /api/webhooks/dodo.

Sites trust the official hub keys built into the plugin. For a self-hosted hub, add its public key on each site with define( 'AGENTWARDEN_HUB_TRUSTED_KEYS', '<base64 key>' ); and its address with define( 'AGENTWARDEN_HUB_URL', 'https://hub.example.com' );.

Processes#

The image runs one of:

  • web: applies pending migrations under a lock, then serves on port 3000. /api/health reports whether the database is reachable.
  • scheduler: sends due client digests at the start of every hour.
  • migrate up|down [steps]|status and set-plan, as one-off commands.

Deploying#

sh
hub/bin/deploy.sh local        # tests, then Docker Compose: hub on http://127.0.0.1:3295, Postgres, scheduler
hub/bin/deploy.sh local down   # stop it; the database volume is kept
hub/bin/deploy.sh fly          # tests, then fly deploy with fly.toml (needs flyctl and FLY_API_TOKEN)

On Fly, migrations run as the release command before new machines start. Vercel has no release command, so run migrations before deploying there (GETTING_ENV_VARS.md in the repository, part 5).

Enterprise plans#

sh
npx tsx bin/set-plan.ts <team-id> enterprise <50|250|unlimited> --by "you@agentwarden.com"
npx tsx bin/set-plan.ts <team-id> none --by "you@agentwarden.com"

In the container: bin/docker-entrypoint.sh set-plan <team-id> enterprise 250 --by "...". Webhooks never change a plan set this way.

Backups and restores#

sh
HUB_ENV=production hub/bin/backup.sh "$DATABASE_URL" /backups 14
HUB_ENV=production hub/bin/restore.sh /backups/agentwarden-hub-<db>-<time>.dump "$EMPTY_DATABASE_URL"
  • backup.sh writes a pg_dump custom-format file and a .sha256 beside it, and keeps the newest 14 (or the count you give).
  • restore.sh refuses a backup that does not match its checksum and a database that already has tables, and restores in one transaction.
  • Both need PostgreSQL client tools at least as new as the server; set PG_BIN to their directory if the ones on PATH are older.
  • hub/bin/backup-restore-test.sh proves the round trip on the test database, table by table. It runs in every hub check and in CI.

Run a restore drill before launch and after any change to the database setup.

Checks#

bin/hub-check.sh runs the type check, lint, unit tests against Postgres, the migration round trip, the production build, browser tests, ShellCheck, and the backup and restore round trip.