Configure the deployment's public origin and shared session secret before choosing login providers or restricting registration.
Required configuration
BETTER_AUTH_SECRET=<openssl rand -hex 32>
BETTER_AUTH_URL=https://sim.yourdomain.com
NEXT_PUBLIC_APP_URL=https://sim.yourdomain.comReplace the secret placeholder with the output of openssl rand -hex 32. Use your exact public origin, including scheme, with no trailing slash. Production Compose derives BETTER_AUTH_URL from NEXT_PUBLIC_APP_URL; see Docker.
The app and realtime services must use the same BETTER_AUTH_SECRET. They share database sessions; a mismatch prevents authenticated socket connections. An incorrect public origin can cause rejected sign-in or redirect loops.
If the deployment serves additional origins, list them explicitly:
TRUSTED_ORIGINS=https://www.example.com,https://app.example.comEmail and password
Email/password sign-in and signup are enabled by default. To require email verification:
EMAIL_VERIFICATION_ENABLED=trueVerification is enforced only when a mail provider is configured. Test email delivery before requiring verification: a configured provider that cannot deliver still prevents new accounts from completing verification. Without a provider, verification is not enforced and invitations and password-reset mail are not delivered.
Social login
These providers sign members in to Sim itself. Integration account connections use separate callback paths.
| Provider | Variables | Login callback |
|---|---|---|
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | https://<host>/api/auth/callback/google | |
| GitHub | GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | https://<host>/api/auth/callback/github |
| Microsoft | MICROSOFT_CLIENT_ID / MICROSOFT_CLIENT_SECRET | https://<host>/api/auth/callback/microsoft |
Set both credentials to make a provider available on the login page. Microsoft is registered only when both values are present.
To keep credentials for integrations while disabling the corresponding login method:
DISABLE_GOOGLE_AUTH=true
DISABLE_GITHUB_AUTH=true
DISABLE_MICROSOFT_AUTH=trueGoogle and Microsoft share their client credentials with integrations. Register their login callback alongside the integration callbacks on the same client; see Integrations and OAuth.
Control registration and sign-in
| Variable | Effect |
|---|---|
DISABLE_REGISTRATION=true | Blocks new email/password, email OTP, and social accounts. Existing accounts can sign in, including to accept workspace invitations. SSO registration is unaffected. |
DISABLE_EMAIL_SIGNUP=true | Blocks new email/password and email OTP registrations. Existing accounts can still sign in through those methods. |
EMAIL_PASSWORD_SIGNUP_ENABLED=false | Disables email/password and email OTP sign-in and signup, including for existing accounts. |
ALLOWED_LOGIN_DOMAINS | Comma-separated email domain allowlist, such as acme.com,acme.co.uk. Applies to email/password and email OTP sign-in as well as email signup. |
ALLOWED_LOGIN_EMAILS | Comma-separated address allowlist. An address or its domain may satisfy the allowlists. |
BLOCKED_SIGNUP_DOMAINS | Comma-separated blocked domains. Blocks signup, sign-in, and executions for addresses in those domains, including subdomains. |
BLOCKED_EMAILS | Comma-separated banned addresses. Blocks signup, sign-in, and executions. |
SIGNUP_MX_VALIDATION_ENABLED=true | Checks email/password signup for a domain with no MX record or a blocked mail backend. |
BLOCKED_EMAIL_MX_HOSTS | MX-host substrings to reject when MX validation is enabled. |
Email allowlists do not filter first-time Google, GitHub, or Microsoft sign-in. To restrict social access, disable login providers you have not vetted or restrict membership through your identity provider and use SSO. MX validation applies only to email/password signup, not sign-in or email OTP. Registration-disabled and blocked-domain/address controls also cover social accounts.
For example, an installation using SSO while allowing existing company email accounts to sign in can set:
ALLOWED_LOGIN_DOMAINS=acme.com
DISABLE_EMAIL_SIGNUP=true
SSO_ENABLED=true
NEXT_PUBLIC_SSO_ENABLED=trueThis does not restrict enabled social providers to acme.com. Configure or disable those login methods separately.
SSO (SAML and OIDC)
For a standard billing-disabled self-hosted deployment, enable the enterprise suite:
ENTERPRISE_ENABLED=true
NEXT_PUBLIC_ENTERPRISE_ENABLED=trueOr enable SSO alone:
SSO_ENABLED=true
NEXT_PUBLIC_SSO_ENABLED=trueSet both the server flag and its UI counterpart. Register providers under Settings → Organization → Single sign-on. A provider can belong to an organization or be registered without one.
Most other enterprise features read settings from the organization that owns a workspace. Set INSTANCE_ORG_NAME to place new members in one organization, or provision organizations through the Admin API. See SSO and Self-hosted enterprise features for provider setup, organization patterns, and billing-enabled behavior.
Behind a load balancer
Tell Better Auth which forwarding hops to trust when resolving client IPs:
AUTH_TRUSTED_PROXIES=10.0.0.0/24,192.0.2.10Use your proxy addresses or CIDRs. Better Auth reads X-Forwarded-For from right to left, skips trusted proxies, and uses the first untrusted address for session records and IP checks. A range that also trusts client traffic defeats this boundary. See Security.
Sign in with Sim
Sim also acts as an OAuth 2.0 authorization server, using authorization code with PKCE. It supports API authorization rather than OpenID Connect identity: it does not issue ID tokens. See CLI authentication.
Access tokens are opaque and last one hour. Refresh tokens rotate on use, and each login has a fixed thirty-day lifetime that refresh does not extend. Validation checks current grants: revoking access under Settings → General → Authorized apps stops the app on its next request. Scheduled token cleanup runs independently of sign-in activity.
DISABLE_AUTH=true disables OAuth sign-in and discovery because these require a real member session. Older servers without OAuth support return 404 from /.well-known/oauth-authorization-server; the CLI can fall back to pairing-code login.
Client registration
MCP clients can use the public registration endpoint at /api/auth/oauth2/register. It accepts reviewed callback formats, requires PKCE, and accepts at most 10 redirect URIs in a JSON body capped at 32 KiB. Its per-IP bucket holds 20 registration tokens and refills 20 each minute. Registration grants no resource access by itself. Members must consent, and each MCP grant is narrowed to the API or Search resource it addresses.
The available scopes are offline_access, api:read, api:write, and search:read. API and Search resource scope families remain distinct. Public registration permits HTTPS callbacks, loopback HTTP callbacks, and the explicitly supported Cursor native callback; it does not accept arbitrary custom URI schemes.
Operators create first-party and confidential clients. Both db:migrate and the development db:push command install OAuth lifecycle triggers and register the Sim CLI, preserving existing grants and client customizations on repeat runs. From a source checkout, register another app with:
DATABASE_URL=… \
BETTER_AUTH_SECRET=… \
OAUTH_CLIENT_ID=my-app \
OAUTH_CLIENT_NAME="My App" \
OAUTH_REDIRECT_URIS=https://my-app.example/callback \
OAUTH_SCOPES=api:read \
bun run apps/sim/scripts/create-oauth-client.tsAdd OAUTH_CLIENT_PUBLIC=true for a native or CLI app that cannot keep a secret. Confidential clients use client_secret_basic; the command prints the authentication method and prints the client secret once. The secret cannot be read back.
Operator-registered redirect URIs must use HTTPS or HTTP on a loopback address. They match exactly, except that loopback callbacks may use any port.
Authorization and upgrades
Organization admins can restrict OAuth App Access under Credentials & Access in permission groups. Workspace requests use the group governing that workspace; authorization, issuance, refresh, and account-level billing/audit reads use the organization's default group. CLI Access also applies to the Sim CLI. Members can still inspect and revoke existing grants when OAuth app access is restricted.
Apply database migrations before a new app version. When upgrading from a version without the OAuth token-family lifecycle, drain older app instances before accepting OAuth traffic so all instances enforce the same refresh and revocation rules.
Disable authentication
DISABLE_AUTH=trueRequests use a shared anonymous session.
Anyone who can reach the instance can act through that session. Use this only for a single-user installation on a private network; do not expose it through an internet-facing ingress.
Other controls
| Variable | Effect |
|---|---|
DISABLE_INVITATIONS=true / NEXT_PUBLIC_DISABLE_INVITATIONS=true | Disable workspace invitations globally. |
DISABLE_PUBLIC_API=true / NEXT_PUBLIC_DISABLE_PUBLIC_API=true | Disable the public API globally. |
ADMIN_API_KEY | Enables Admin API GitOps operations and organization provisioning. |
Set both server and NEXT_PUBLIC_ flags where a pair is listed. The server flag enforces the restriction; its counterpart controls the UI.
Verify authentication
Sign out and sign back in at the public origin, then open a workflow in two browser windows and confirm edits propagate. Test each enabled login method. If verification is required, create a test account and confirm the message arrives and the verification succeeds. Use Verify your install for deployment checks.