Authentication

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.com

Replace 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.com

Email and password

Email/password sign-in and signup are enabled by default. To require email verification:

EMAIL_VERIFICATION_ENABLED=true

Verification 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.

ProviderVariablesLogin callback
GoogleGOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECREThttps://<host>/api/auth/callback/google
GitHubGITHUB_CLIENT_ID / GITHUB_CLIENT_SECREThttps://<host>/api/auth/callback/github
MicrosoftMICROSOFT_CLIENT_ID / MICROSOFT_CLIENT_SECREThttps://<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=true

Google 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

VariableEffect
DISABLE_REGISTRATION=trueBlocks 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=trueBlocks new email/password and email OTP registrations. Existing accounts can still sign in through those methods.
EMAIL_PASSWORD_SIGNUP_ENABLED=falseDisables email/password and email OTP sign-in and signup, including for existing accounts.
ALLOWED_LOGIN_DOMAINSComma-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_EMAILSComma-separated address allowlist. An address or its domain may satisfy the allowlists.
BLOCKED_SIGNUP_DOMAINSComma-separated blocked domains. Blocks signup, sign-in, and executions for addresses in those domains, including subdomains.
BLOCKED_EMAILSComma-separated banned addresses. Blocks signup, sign-in, and executions.
SIGNUP_MX_VALIDATION_ENABLED=trueChecks email/password signup for a domain with no MX record or a blocked mail backend.
BLOCKED_EMAIL_MX_HOSTSMX-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=true

This 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=true

Or enable SSO alone:

SSO_ENABLED=true
NEXT_PUBLIC_SSO_ENABLED=true

Set 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.10

Use 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.ts

Add 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=true

Requests 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

VariableEffect
DISABLE_INVITATIONS=true / NEXT_PUBLIC_DISABLE_INVITATIONS=trueDisable workspace invitations globally.
DISABLE_PUBLIC_API=true / NEXT_PUBLIC_DISABLE_PUBLIC_API=trueDisable the public API globally.
ADMIN_API_KEYEnables 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.