Skip to content

Configuration

All configuration is environment-driven with an LLMPROXY_ prefix. There is no config file.

A malformed value (for example a non-numeric port) silently falls back to the default, so check the value when a setting looks like it was ignored.

Environment variables

Variable Default Meaning
LLMPROXY_DATABASE_URL llmproxy.db SQLite file path, or a postgres:// URL. See database URLs
LLMPROXY_KEY_SECRET empty Explicit HMAC / encryption secret. When empty, a random secret is generated and stored in the secret file
LLMPROXY_SECRET_FILE .llmproxy/secret Where the generated secret lives (created mode 0600 on first run). Ignored when LLMPROXY_KEY_SECRET is set
LLMPROXY_HOST 127.0.0.1 Bind address
LLMPROXY_PORT 4000 Bind port
LLMPROXY_ALLOW_NONLOCAL false Allow binding a non-loopback address in local (no-SSO) mode. Accepts Go bool syntax. No effect in SSO mode. See the loopback guard
LLMPROXY_OIDC_ISSUER empty OIDC issuer URL. Unset means local single-admin mode; set means SSO mode
LLMPROXY_OIDC_CLIENT_ID empty OAuth client id. Required in SSO mode
LLMPROXY_OIDC_CLIENT_SECRET empty OAuth client secret. Required in SSO mode
LLMPROXY_OIDC_REDIRECT_URL empty Absolute callback URL, https://your-proxy/auth/callback. Required in SSO mode. An https:// value also marks session cookies Secure (as does any request arriving over TLS or with X-Forwarded-Proto: https), and its host is accepted by the same-origin check when a reverse proxy rewrites Host
LLMPROXY_OIDC_SCOPES openid profile email Space-separated scopes requested from the IdP
LLMPROXY_OIDC_GROUPS_CLAIM groups Userinfo claim (a string array) read for group membership
LLMPROXY_OIDC_ADMIN_GROUP empty Members get the admin role, reconciled on every login. Empty means SSO users are never auto-promoted
LLMPROXY_OIDC_REQUIRED_GROUP empty When set, users outside this group cannot log in at all (403 sso_group_required)
LLMPROXY_SESSION_TTL 12h Browser session lifetime. Sessions are server-side rows; logout and POST /admin/v1/principals/{id}/revoke-sessions invalidate them immediately by deletion
LLMPROXY_LOCAL_ADMIN_NAME local-admin Name of the admin principal bootstrapped in local mode
LLMPROXY_ADMIN_PASSWORD empty Browser password for the local admin. When empty, a random one is generated at first boot into the password file. See the admin password
LLMPROXY_ADMIN_PASSWORD_FILE .llmproxy/admin-password Where the generated admin password lives (created mode 0600). Ignored when LLMPROXY_ADMIN_PASSWORD is set
LLMPROXY_ADMIN_PASSWORD_DISABLED false Disable password login entirely, for SSO-only deployments
LLMPROXY_CATALOG_TTL 5s Alias-resolution cache TTL. Admin API mutations invalidate the cache immediately; this TTL bounds staleness for changes made directly in the database or from another instance
LLMPROXY_MAX_BODY_BYTES 10485760 (10 MiB) Request body ceiling on the /v1 endpoints. Oversize requests get 413 request_too_large
LLMPROXY_MAX_EMBEDDING_BATCH 2048 Maximum items in an embeddings input array. 0 or negative disables the check
LLMPROXY_PRICING_FILE empty Path to a pricing feed JSON loaded at startup. Stored only when its version differs from the active feed. Format in pricing
LLMPROXY_TRANSPARENT_ANTHROPIC_BASE_URL https://api.anthropic.com Target of the transparent Anthropic relay. Empty disables the relay
LLMPROXY_LOG_LEVEL info debug, info, warn or error. At info, every request logs one line (method, path, status, duration); health checks and static assets appear only at debug. Client and server errors log at warn/error. Logs go to stderr and never contain request or response content

Durations use Go syntax: 5s, 90m, 12h, 1h30m.

Database URLs

Anything starting with postgres:// or postgresql:// selects Postgres (via pgx, max 20 connections):

LLMPROXY_DATABASE_URL=postgres://llmproxy:secret@db.internal:5432/llmproxy

Everything else is a SQLite file path (an optional sqlite:// prefix is stripped). SQLite is opened with WAL journaling, a 30 s busy timeout, synchronous=NORMAL and max 8 connections:

LLMPROXY_DATABASE_URL=/var/lib/llmproxy/llmproxy.db

The schema is identical on both backends and is created idempotently on boot.

The secret

One secret underpins all cryptography in the proxy. It is resolved once at startup: LLMPROXY_KEY_SECRET verbatim if set, otherwise the contents of LLMPROXY_SECRET_FILE, generated (32 random bytes) on first run.

What it protects, via derived keys:

How
API keys Stored only as HMAC-SHA256 digests under this secret
Provider credentials Encrypted with AES-256-GCM, since they must be recoverable to forward upstream
Sessions The cookie holds an opaque token stored server-side as a keyed hash

Four consequences:

  • Losing the secret stops every API key validating and makes every stored provider credential undecryptable. Recovery means minting new keys (the CLI still works, since it writes to the database directly) and re-entering each provider's api_key. Principals, models and usage history survive.
  • Rotating the secret has exactly the same effect as losing it. There is no dual-key rotation. Treat it as a planned re-keying event.
  • The CLI and the server must see the same secret, through the same environment or the same secret file, or CLI-minted keys will not validate.
  • Back it up separately from the database. If both leak together, the attacker can verify keys offline and decrypt provider credentials.

The admin password

The built-in UI offers a password login for the local admin principal, with or without SSO configured. In SSO mode it is the break-glass path: an IdP outage cannot lock you out of your own proxy.

Resolution order: LLMPROXY_ADMIN_PASSWORD verbatim if set, otherwise the contents of LLMPROXY_ADMIN_PASSWORD_FILE, generated on first boot.

  • To rotate a generated password, delete the file and restart.
  • To run SSO-only, set LLMPROXY_ADMIN_PASSWORD_DISABLED=1.
  • The password is never stored in the database and is compared in constant time. A failed attempt is delayed by 400 ms as a blunt brute-force damper; put real rate limiting in your reverse proxy if the login page is internet-facing.

A successful login issues the same server-side session as SSO, carrying the principal's role. The local admin's session can use the full admin API, with mutations origin-checked.

CLI flags

llmproxy serve accepts three flags that override the corresponding environment variables:

Flag Overrides
-host <addr> LLMPROXY_HOST
-port <n> LLMPROXY_PORT
-allow-nonlocal LLMPROXY_ALLOW_NONLOCAL (sets it true; there is no flag to force it false)

Everything else is environment-only. The key, relay-token and principal subcommands take no server flags; they read LLMPROXY_DATABASE_URL, LLMPROXY_KEY_SECRET, LLMPROXY_SECRET_FILE and LLMPROXY_LOCAL_ADMIN_NAME to find the database and the secret.