.env; the Homebrew service reads $(brew --prefix)/etc/ai-development-environment.env; the container image takes --env flags or an env file. .env.example in the repository mirrors this page.
APP_SECRET is the only required variable. Everything else has a working default.
Core
string
required
The root secret. Must be base64 or hex encoding of exactly 32 random bytes — a passphrase is rejected. Generate one with
openssl rand -base64 32.Session signing, credential encryption, and install-link signing are each derived from it with a separate HKDF label, so a leak of one derived key tells an attacker nothing about the others. Back it up: without it, stored credentials cannot be read.The Homebrew service generates one into its environment file on first start if you have not set one.string
The value(s) being replaced during a rotation, comma-separated. Stored credentials sealed under a listed root are re-encrypted at startup. Remove it once the server has started cleanly. See rotating APP_SECRET.
string
Comma-separated list of origins this server may be reached at. Drives Better Auth’s CSRF and post-login redirect allowlist and the Next.js dev-server allowlist.Entries may be a bare host (
app.example.com), a host and port (10.0.0.5:3000), or a full origin (https://app.example.com). An entry without a port matches any port; an entry with one is exact.Optional. Outside production, localhost, 127.0.0.1, and [::1] are always trusted in addition to whatever you list, so a source checkout usually needs nothing here.In production, leaving both this and PUBLIC_BASE_URL unset puts the server in inferred mode: it trusts whatever host each request arrived on. Sign-in works on any hostname without configuration, and a cross-site request is still rejected — a browser sets Host to the real destination, so an attacker’s page cannot make its own origin look trusted.What inferred mode gives up is control over the absolute URLs this server generates. A direct request carrying a forged Host — no victim or cookie involved — can steer the OAuth redirect_uri, iOS enrollment and install links, and the GitHub webhook URL at a host of the caller’s choosing. Setting either variable pins them. The server logs a warning at startup when it enters this mode.A leading *. wildcard (*.example.com) is accepted outside production only. A wildcard trusts every host under it for both CSRF and post-login redirects, so it is rejected outright when NODE_ENV=production.string
The origin external systems use to reach this server, when that differs from where the dashboard is served. Used to build iOS enrollment and over-the-air install URLs and to register GitHub, GitLab, and Jira webhooks. It is automatically trusted as though listed in
APP_ORIGINS.These integrations require publicly trusted HTTPS and are offered only when this resolves to a public https origin.Setting this is enough on its own to leave inferred mode, so a deployment that only cares about pinning generated URLs does not also need APP_ORIGINS.string
Path to a PEM bundle containing additional certificate authorities trusted by the Node.js process. Set this when a self-hosted GitLab instance uses a certificate issued by a private CA. The path must be readable by the AIDE server or mounted into its container.This extends normal certificate verification. AIDE does not provide a GitLab certificate upload or insecure TLS bypass.
boolean
default:"false"
Whether
x-forwarded-host and x-forwarded-proto may be believed. Enable only when a reverse proxy in front of this server sets them and strips client-supplied copies. APP_ORIGINS still constrains the resulting value.string
default:"file:./prisma/dev.db"
SQLite connection string. Only
file: URLs are accepted. Read by both the runtime client and the Prisma CLI.string
default:"127.0.0.1"
Interface the HTTP server binds to. Standard Next.js variable.
number
default:"3000"
HTTP port. The Homebrew service defaults to
3090 instead. Also supplies the port in the development origin defaults.Authentication
string
default:"password"
password, oidc, or both. The server enforces the mode on its routes; hiding a form in the browser does not enable a disabled method.AUTH_MODE is oidc or both. Supply either a discovery URL or all three explicit endpoint URLs — not both. Better Auth always uses PKCE for the server-to-provider exchange, and the iOS app-to-server exchange independently requires S256 PKCE. Neither exchange has a PKCE environment variable. Issuer validation defaults to false and can be enabled with the setting below. See Authentication for the full workflow, one-minute native authorization code, and coordinated upgrade requirement.
Credential storage
string
default:"database"
database, vault, or keychain. Homebrew installs default to keychain; npm, Linux, and container installs default to database.Database storage is always encrypted with a key derived from APP_SECRET. There is no plaintext mode and no separate encryption key to configure. Vault and Keychain storage never use the derived key.CREDENTIAL_STORAGE_TYPE=vault. See credential storage.
Agents and live updates
Change
AGENT_WS_PORT and NEXT_PUBLIC_AGENT_WS_URL together. The first moves the listener; the second tells the browser where to find it. Out of sync, the dashboard loads but never receives live updates.
Builds and artifacts
Install manifests mint expiring links signed with a key derived fromAPP_SECRET, so they survive a restart. Rotating APP_SECRET invalidates outstanding links, which expire in six hours regardless.
GraphQL tooling
Development only
None of these are read by a production install.Rotating APP_SECRET
Rotation signs every user out and invalidates outstanding install links. Stored credentials are preserved as long as the old value is supplied:APP_SECRET_PREVIOUS can be removed. The step is idempotent, so an interrupted start simply resumes.
Without APP_SECRET_PREVIOUS, a changed APP_SECRET refuses to start rather than silently losing access to stored credentials. APP_SECRET_PREVIOUS accepts several values, comma-separated, so a rotation can roll across replicas.