AppAIGatewayDocs
Self-hosting

Deploy to Cloudflare

Deploy from the Cloudflare form and initialize your account privately.

For the simplest terminal setup, install @maxceem/agw and run agw deployment setup --name my-gateway --no-domain. It creates the resources, saves its recovery journal and connects the new gateway. See CLI. The button below is an alternative for a deployment maintained through a GitHub fork.

Setup acts on your Cloudflare account through Wrangler, and reuses whatever Wrangler is already authorized with: an earlier wrangler login, or CLOUDFLARE_API_TOKEN in the environment. It opens a browser only when it finds neither. Setting CLOUDFLARE_API_TOKEN is what keeps a browser out of it; add --no-input so nothing else prompts either, and supply the values it would have asked for.

The first deployment command downloads the gateway build belonging to that CLI version: one archive, published with the project's GitHub release. It is checked against a SHA-256 built into the CLI before anything is unpacked, and kept under $XDG_CACHE_HOME/agw (~/.cache/agw, or %LOCALAPPDATA%\agw on Windows), so later commands reuse it. An archive that does not match that hash is refused.

On a machine with no route to GitHub, download gateway-<version>.tar.gz from the release matching agw --version elsewhere, copy it over, and name it:

agw deployment setup --name my-gateway --no-domain \
  --release-archive ./gateway-0.1.5.tar.gz

The same hash is checked, so a file that travelled by hand is trusted no further than one that arrived over the network. AGW_RELEASE_ARCHIVE sets the same path for every deployment command.

Prepare the deployment values

Generate a vault key with openssl rand -base64 32 and a public deployment ID with node -p "crypto.randomUUID()". Save the vault key privately. Preserve the same deployment ID across updates and custom domains.

Back up the vault key

Losing SECRET_VAULT_LOCAL_KEK_V1 makes stored provider credentials unreadable. Keep it in a password manager or another protected backup.

Deploy your fork

Deploy to Cloudflare

The form creates your fork and Worker and connects later pushes to Workers Builds. Fill in these values:

FieldValue
SECRET_VAULT_LOCAL_KEK_V1Your private vault key.
DEPLOYMENT_IDYour public UUID; keep it unchanged.
SECRET_VAULT_MODElocal
SECRET_VAULT_LOCAL_KEK_CURRENT_VERSION1
ALLOW_ADDITIONAL_REGISTRATIONSfalse

The deploy script generates internal signing secrets once, applies migrations and deploys the console and Worker. Your saved plain DEPLOYMENT_ID must remain in the build configuration or build environment on later builds; do not generate a new one. The script refuses deployment when this value is absent.

Check https://YOUR-WORKER.workers.dev/v1/healthz and confirm "vault":"ok". Then check /v1/cli/capabilities and confirm the expected deployment ID.

Initialize and claim privately

An empty deployment lets its first person register in the console. To initialize through the CLI instead, clone your fork locally, install Node.js 22.19 or later, and run the helper from that checkout. Once the helper creates its account, ordinary registration cannot take ownership of it:

node scripts/bootstrap-account.mjs https://YOUR-WORKER.workers.dev
npm install -g @maxceem/agw
agw deployment connect --url https://YOUR-WORKER.workers.dev --key-stdin < .agw-bootstrap/management-key
agw account claim

The helper saves retry proofs before its request and writes the management credential to .agw-bootstrap/management-key with private permissions. It never prints the credential. Keep that directory if a response is lost and repeat the same command. Complete initialization promptly because protected remote key recovery lasts 15 minutes.

Open the claim URL in your own browser, enter the separate terminal code, compare the account, and create or sign into your human account. Choose whether to keep CLI access. Existing accounts continue to sign in normally. If you enable additional registration, each new person receives a separate account and no access to this claimed one.

Initialize straight after deploying

A deployment with no account yet belongs to whoever takes it first, whether by registering in the console or by running the helper above. Do that yourself as soon as the health check passes. A deployment nobody has taken holds no provider credentials, so nothing of yours is exposed; if someone else does get there first, delete its D1 database, create it again, apply the migrations and deploy once more to start from empty.

Follow Quickstart to add a provider and an app, or Custom domain and rate limiting to add a hostname.

On this page