Skip to content

Environment variables

Every environment variable the server, the inbox, the self-host bundle and your agent app read.

All configuration comes from environment variables. The server validates them at boot and refuses to start on invalid values.

Variable Default Notes
DATABASE_URL Required. Postgres URL; the pooled one in production.
DIRECT_URL Direct, non-pooled URL used by prisma migrate deploy. Not needed at runtime.
SIGNING_KEY Ed25519 private key, PKCS8 PEM. The same value on every instance. Keep it in a secret store. Required in production; in development a key is generated and printed.
SIGNING_KEY_PREVIOUS The old key during rotation; its public key stays published.
PUBLIC_URL http://localhost:3000 The address people open. Used for cookies, invite and reset links and OAuth callbacks (PUBLIC_URL/api/v1/auth/oauth/<provider>/callback).
ORG_NAME Intentlock Name of the organization created on first boot. The setup page can rename it.
PORT 3000 Port the server listens on.
TRUST_PROXY 0 Number of reverse proxies in front of the server: 1 behind the bundled nginx. Never more than the real number, or clients can spoof their IP.
API_KEY_PEPPER empty Extra secret mixed into API key hashes. Changing it invalidates every API key.
CORS_ORIGINS Only if the inbox is served from another origin. Avoid it; use one origin.
LICENSE_FILE Path to a license file. Unset means Community edition.
SMTP_URL For example smtps://user:pass@smtp.example.com:465. Set: invite and reset links are emailed and “forgot password” appears. Unset: links are only shown to copy.
SMTP_FROM Sender, for example Intentlock <intentlock@acme.dev>. Required with SMTP_URL.
HOLD_WEBHOOK_URL Optional https:// Slack or Discord incoming webhook. Each new hold is posted with the agent, person, tool and argument names, but never argument values.

With SMTP set, every new hold is also emailed to the team members who may approve it, including the arguments cut to 500 characters. Each person can turn these emails off on their Account page. A failed send is retried once, and if it still fails it is audited as hold_notify_failed. Holds and tool calls never wait for a notification.

Brevo example. Brevo’s free plan works with Render’s free tier, which blocks outbound SMTP ports 25, 465 and 587. Use port 2525, the login shown under SMTP & API → SMTP, and an SMTP key (not an API key). Write the @ in the login as %40:

Terminal
SMTP_URL=smtp://9a1b2c001%40smtp-brevo.com:<smtp-key>@smtp-relay.brevo.com:2525
SMTP_FROM="Intentlock <intentlock@your-domain.dev>"

The SMTP_FROM address must be a sender or domain you verified in Brevo. | GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | | Both set: “Continue with Google”. OAuth client type “Web application”. | | GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET | | Both set: “Continue with GitHub”. | | DATABASE_POOL_MAX | 10 | Connections per instance. Instances times this must stay under the database’s connection limit. | | DATABASE_POOL_TIMEOUT_MS | 5000 | How long a query waits for a free connection before the request answers 503. | | DATABASE_TX_MAX_WAIT_MS | 2000 | How long a transaction waits to start before answering 503. | | DATABASE_TX_TIMEOUT_MS | 5000 | How long a transaction may run before answering 503. | | LOG_LEVEL | info | fatal, error, warn, info, debug, trace or silent. | | NODE_ENV | development | production in deployments. | | INTENTLOCK_DEMO | 0 | 1: completing setup also creates sample users with printed passwords. Never in a real install. |

Variable Default Notes
API_URL http://localhost:3000 The server’s address behind the inbox’s /api/* rewrite. Read at build time.
DEMO_RUNNER_URL http://localhost:8790 The local demo runner behind /demo-runner/*. Development and recording only.
NEXT_PUBLIC_DOCS_URL An http(s) URL for a “Docs” link in the sidebar. Read at build time. Unset hides the link.

These are read by docker-compose.selfhost.yml from .env, next to the server variables above.

Variable Default Notes
POSTGRES_PASSWORD Required. Password of the bundled Postgres.
HTTP_PORT 8080 Port nginx listens on.
INTENTLOCK_VERSION the bundle’s release (0.2.1) Image tag to run. Change it to upgrade.

The bundle sets DATABASE_URL, DIRECT_URL and TRUST_PROXY itself.

Variable Notes
INTENTLOCK_URL The server’s API address, for example https://intentlock.acme.dev/api.
INTENTLOCK_API_KEY The agent’s API key (il_live_...).
LLM_PROVIDER, LLM_BASE_URL, LLM_API_KEY, LLM_MODEL Read by providerFromEnv(). See LLM providers.

Model keys and other secrets of your agent never go to the Intentlock server. The repository’s demo agents and evals also read LLM_* and GITHUB_TOKEN, locally only.