DocsDeploy and operate

Self-hosting

Run Gatehouse in your own network with Docker or Kubernetes, manage the master key, and take backups.

Gatehouse is one Node.js process with one SQLite database on a volume. There's no other service to run. It works fully air-gapped.

What Gatehouse connects to

Gatehouse makes no outbound calls except to what you configure:

  • the MCP servers you add,
  • your identity providers (for SSO),
  • your SMTP server (for invites and resets),
  • Slack (for approvals), if you turn it on,
  • your audit streaming destination.

There is no telemetry, license check or phone-home.

Docker Compose

openssl rand -base64 32 > deploy/master.key && chmod 600 deploy/master.key
docker build -t gatehouse .

Edit deploy/docker-compose.yml and set at least GATEHOUSE_BASE_URL to the address people and agents will use. Then:

cd deploy && docker compose up -d
docker compose logs gatehouse | grep "setup code"

Open <base url>/setup, enter the code and create the owner account.

The compose file:

  • listens on port 8787,
  • stores data on a named volume mounted at /data,
  • reads the master key from a Docker secret via GATEHOUSE_MASTER_KEY_FILE,
  • runs with a read-only root filesystem and no-new-privileges.

The image runs as the unprivileged node user, sets HOST=0.0.0.0 and GATEHOUSE_ENV=production, and has a health check on /healthz.

Kubernetes with Helm

The chart is in deploy/helm/gatehouse.

kubectl create secret generic gatehouse-key --from-file=master.key=./master.key

helm install gatehouse deploy/helm/gatehouse \
  --set baseUrl=https://gatehouse.example.com \
  --set masterKey.existingSecret=gatehouse-key

Useful values:

Value Purpose
baseUrl Public URL. The MCP endpoint is <baseUrl>/mcp.
orgName Shown in the console and emails.
masterKey.existingSecret A Secret with key master.key. Recommended.
masterKey.command Fetch the key from your KMS or vault at startup instead.
extraEnv, extraEnvFrom SMTP, Slack and other settings. Use extraEnvFrom for secrets.
persistence.size Volume size, 10Gi by default.
ingress.* Expose Gatehouse through your ingress controller.

Run exactly one replica. The database is SQLite on a volume, so the chart uses the Recreate deployment strategy. Expect a short gap during upgrades.

Put TLS in front

Gatehouse serves plain HTTP. Terminate TLS at your load balancer, ingress or reverse proxy, and use an https:// base URL. OAuth for agents and SSO callbacks rely on it.

Behind a proxy, set GATEHOUSE_TRUST_PROXY so audit entries and the IP allow-list see real client addresses. Use the proxy's address range (for example 10.0.0.0/8). Use 1 only if nothing but the proxy can reach Gatehouse, since any client that reaches it directly could otherwise fake its address. In Kubernetes, set trustProxy in the chart values; the chart's NetworkPolicy (on by default) lets only your ingress controller in.

For a single cloud server with HTTPS and backups set up for you, see Deploy on AWS Lightsail. Backups are covered in Backups and restore, and license keys in Licensing.

For a locked-down install, set GATEHOUSE_STDIO_COMMANDS to the programs you allow (like npx,uvx), or GATEHOUSE_DISABLE_STDIO=true to allow remote MCP servers only. See Configuration.

The master key

The master key encrypts every stored credential: server tokens, SSO client secrets and the audit stream secret. It's 32 random bytes, base64-encoded:

openssl rand -base64 32

Gatehouse reads it from the first of these that's set:

  1. GATEHOUSE_MASTER_KEY_COMMAND: a command that prints the key. The key never touches disk.
    • AWS KMS: aws kms decrypt --ciphertext-blob fileb:///kms/key.enc --query Plaintext --output text
    • Vault: vault kv get -field=key secret/gatehouse
  2. GATEHOUSE_MASTER_KEY_FILE: a file with the key, for Docker and Kubernetes secrets.
  3. GATEHOUSE_MASTER_KEY: the key itself.

With GATEHOUSE_ENV=production, the default in the image, Gatehouse refuses to start without one of these. Outside production it generates data/master.key for convenience.

Keep a safe copy of the key. Without it, stored credentials can't be decrypted. People, policies and the audit log stay readable, but you'd need to re-enter every server credential.

Backups

npm run cli -- backup /data/backups/gatehouse-$(date +%F).db

This uses SQLite's VACUUM INTO to write a consistent copy, and it's safe while Gatehouse is running. In Docker:

docker compose exec gatehouse npm run cli -- backup /data/backups/gatehouse-$(date +%F).db

Copy backups off the volume and store the master key separately. To restore, stop Gatehouse, put the backup file in place of /data/gatehouse.db, and start it with the same master key.

Upgrades

Build or pull the new image and restart. Gatehouse updates its database schema on start. Take a backup first.

Email and Slack

Set SMTP_* to send invites and password resets. Without SMTP, admins copy links by hand. Set SLACK_* for Slack approvals. Slack uses Socket Mode, so no inbound connection is needed. See Configuration.