Model gateway (LiteLLM)
Centralize model credentials and budgets behind a bundled LiteLLM proxy.
The model gateway is optional, and most installs start without it. Without the gateway, users bring their own agent subscriptions: they sign in to Claude or Codex directly from the desktop app, exactly as they would on their own machine. Nothing about the base install requires the gateway.
Add the gateway when you want, as an admin:
- Central provider keys. Your Anthropic, OpenAI, or xAI keys live in one place (the LiteLLM proxy container), not on laptops and never inside sandboxes.
- Per-user short-lived keys. The Proliferate server mints a short-lived virtual key for each user; agents and sandboxes only ever see the public gateway URL and that virtual key. Your real provider credentials never reach them.
- Budgets. Spending limits per user and per organization, enforced at the gateway.
Budgets on a self-hosted install are limits, not billing. There is no credits, billing, or top-up UI on self-hosted Proliferate; usage accounting and dashboards live in LiteLLM.
How it works
The gateway is LiteLLM, and the standard Docker
Compose stack can run it for you: litellm and its own Postgres database
(litellm-db) ship as an optional service group in
docker-compose.production.yml, off by default and turned on with a Compose
profile. The image is Proliferate's own build
(ghcr.io/proliferate-ai/proliferate-litellm), preloaded with the model list
Proliferate's harnesses expect (current Claude, GPT, and Grok models, each
mapped to your own provider key). You supply provider keys and a master key;
the Proliferate server uses the master key to mint and revoke per-user
virtual keys, and sandboxes call the gateway's public URL with those virtual
keys. The master key itself stays between the Proliferate server and
LiteLLM, and is never sent to sandboxes.
Prefer to run LiteLLM yourself (a different host, a managed instance, or a custom model list) instead of the bundled service? See external LiteLLM instead below. The Proliferate server only cares about the base URL, public URL, and master key; it does not care who runs the process behind them.
Set up
Add provider keys and secrets
Add the bundled gateway's variables to .env.static in your deploy bundle:
Older copies of .env.production.example have a leftover AGENT_GATEWAY_BIFROST_*
block from before the gateway moved to LiteLLM. The server does not recognize
those names and silently ignores them. If you see that block, delete it and
add the AGENT_GATEWAY_LITELLM_* / LITELLM_* variables below instead.
Expose the gateway publicly
The bundled litellm service is not published outside the Docker network by
default (only the main API is, through Caddy). Cloud sandboxes run outside
your network, so they need a public URL for model traffic. Add a second site
block to the Caddyfile in your deploy bundle, pointing a hostname you
control at the litellm service:
Point DNS for that hostname at the same host, then set it as the public URL
in .env.static:
Bring the gateway up
Run ./bootstrap.sh (first time) or ./update.sh (existing install) from
the deploy directory as usual, then start the gateway's services explicitly.
Compose profiles are opt-in, so the bare up/pull that bootstrap.sh and
update.sh run never touches them:
Re-run those two commands after every ./update.sh to pick up a new
proliferate-litellm image, the same way rebuilding the E2B template keeps
the sandbox runtime in step with a server update.
Screenshot: Terminal - docker compose --profile agent-gateway up -d starting litellm and litellm-db
A terminal bringing up the litellm and litellm-db containers via the agent-gateway Compose profile.
Verify
Start an agent session from the desktop app. The sandbox environment should reference your public gateway URL and a short-lived virtual key rather than any provider credential, and the request should appear in LiteLLM's own logs and spend data under that key.
Screenshot: Desktop app - Settings, model gateway status showing the gateway enabled and reachable
The desktop settings surface confirming the configured gateway is enabled and the sandbox is using a virtual key.
Environment variable reference
| Variable | Purpose |
|---|---|
AGENT_GATEWAY_ENABLED | Turns the gateway integration on. |
AGENT_GATEWAY_LITELLM_BASE_URL | LiteLLM management URL the Proliferate server calls; keep it off the public internet. http://litellm:4000 for the bundled service. |
AGENT_GATEWAY_LITELLM_PUBLIC_BASE_URL | Gateway URL written into sandbox configuration; sandboxes send model traffic here. |
AGENT_GATEWAY_LITELLM_MASTER_KEY | Master key the server uses to mint and manage virtual keys; must match LITELLM_MASTER_KEY on the LiteLLM container. Never sent to sandboxes. |
AGENT_GATEWAY_LITELLM_TIMEOUT_SECONDS | Management API timeout; defaults to 30. |
AGENT_GATEWAY_DEFAULT_USER_BUDGET_USD | Default monthly cap in USD for a personal virtual key. Defaults to 5. |
AGENT_GATEWAY_DEFAULT_ORG_BUDGET_USD | Default cap for organization-wide gateway usage (shared and automation sandboxes). Defaults to 0, which LiteLLM treats as uncapped. |
Bundled-service-only (skip these in external mode):
| Variable | Purpose |
|---|---|
LITELLM_MASTER_KEY | The master key set on the bundled LiteLLM container itself; must match AGENT_GATEWAY_LITELLM_MASTER_KEY. |
LITELLM_POSTGRES_PASSWORD | Password for the bundled litellm-db Postgres instance. |
LITELLM_POSTGRES_DB / LITELLM_POSTGRES_USER | Optional overrides; default to litellm / litellm. |
ANTHROPIC_API_KEY / OPENAI_API_KEY / XAI_API_KEY | Provider keys passed straight into the bundled container's environment. Set only the providers you use. |
PROLIFERATE_LITELLM_IMAGE / PROLIFERATE_LITELLM_IMAGE_TAG | Override the LiteLLM image or tag. Defaults to ghcr.io/proliferate-ai/proliferate-litellm:stable. |
Budgets
AGENT_GATEWAY_DEFAULT_USER_BUDGET_USD (default $5) caps what a single
user can spend through their personal virtual key. Once a shared sandbox or
automation run authenticates as the organization, that traffic is capped
separately by AGENT_GATEWAY_DEFAULT_ORG_BUDGET_USD (default 0, meaning
uncapped). These are lifetime caps with no automatic reset: when a key hits
its budget, the gateway rejects further model calls until an admin raises
that key's budget in LiteLLM directly. Provider spend itself is whatever your
provider accounts bill; LiteLLM's own logs are the place to watch usage per
key.
The bundled model list
The bundled image ships a fixed, checked-in model list mapping model names (current Claude, GPT, and Grok releases) to your provider keys; it is not a general-purpose "add any model" proxy. That covers every model Proliferate's supported harnesses ask for. If you need a different provider (Azure OpenAI, Bedrock, a self-hosted model server) or a custom model list, run LiteLLM yourself instead.
External LiteLLM instead
If you'd rather run LiteLLM outside the bundled Compose services, skip the
agent-gateway profile entirely and point the same three
AGENT_GATEWAY_LITELLM_* variables at your own instance: its admin URL, its
public URL, and its master key. The Proliferate server does not distinguish
between the bundled container and an externally run one; it just calls
whatever URLs you configure. This is the path for a custom model list, a
managed LiteLLM service, or a LiteLLM instance you already run for other
purposes.
Removing the gateway
Set AGENT_GATEWAY_ENABLED=false, run ./update.sh, and if you were running
the bundled service, stop it too:
Users fall back to signing in to their agents directly with their own subscriptions, the same as an install that never enabled the gateway.