The Settings API provides configuration management for the BAASIX application. Settings can be stored in the database (for runtime configuration) or set via environment variables (for server configuration).
The auth block lets clients discover which login methods are actually enabled (and which social providers are
credentialed) without hardcoding assumptions. See Discovering Enabled Auth
Methods for the full field reference.
The public GET /settings response only ever includes the default portion of session_limits (shown above as
the flattened { "web": ..., "mobile": ... } object), plus the derived legacy hint keys web_session_limit and
mobile_session_limit computed from it for older clients. Role IDs, per-role limits, and per-user overrides are
never exposed on this public endpoint — only authenticated admin requests can see the full session_limits.roles
map.
# Get global settingscurl -X GET "http://localhost:3000/settings"# Get tenant-specific settingscurl -X GET "http://localhost:3000/settings?tenant_id=tenant-123"
A tenant's session_limits fully replaces the global session_limits when both exist — values are not deep merged.
See the Session Limits Feature guide for the full resolution order and
per-user override behavior.
{ "default": { "web": n, "mobile": n }, "roles": { "<role-id>": { "web": n, "mobile": n } } }. -1=unlimited, 0=disabled. Tenant value fully replaces the global value (no merge). See Session Limits Feature.
null
The public GET /settings endpoint only exposes session_limits.default (plus derived web_session_limit /
mobile_session_limit hint keys for older clients) — never the roles map. session_limits is also present on the
baasix_User record as a nullable JSON field for per-user overrides; null/absent means inherit from the
role/default resolution.
These default to secure (on) — set to false only to relax a protection. SQL-injection protection (identifier allowlisting and JSONB numeric-operand validation) is always on and has no toggle.
Variable
Description
Default
PROTECT_PRIVILEGE_FIELDS
Privilege fields (role_Id, tenant_Id, userCreated_Id, userUpdated_Id, emailVerified, hidden fields) are excluded from a fields:["*"] grant and must be named explicitly. Admins are exempt. Tri-state: true (default) — password denied to non-admins even when explicitly granted; allow-password — a non-admin role may set password when explicitly granted (fields:["*","password"], e.g. delegated password reset); false — protection off. Passwords are always auto-hashed.
true
PROTECT_IS_PUBLIC_FIELD
Make baasix_File isPublic (which serves a file publicly, cross-tenant, no auth) opt-in: writable only when named explicitly in a permission, not via a broad * grant. Default off (backward compatible).
false
EXPOSE_ERROR_DETAILS
Include raw DB/internal error text in responses. Default off in production (raw PG messages leak schema and are an injection oracle); on otherwise. Production returns a generic message + correlation id.
(prod: false)
STORAGE_PATH_CONFINEMENT
Confine all local-disk file operations within the storage root (blocks path traversal). Null bytes are always rejected regardless.
true
STORAGE_FOLDER_STRUCTURE
Organize stored files into a per-tenant / per-user / system folder structure (tenants/{t}/users/{u}/, tenants/{t}/system/, users/{u}/, system/). Default off (flat). Existing files are unaffected (legacy flat layout). Migrate existing files via the admin endpoint POST /files/migrate-storage-structure (supports ?dryRun=true; crash-safe, idempotent, resumable).
false
ASSET_XSS_PROTECTION
Force executable upload types (text/html, image/svg+xml, */javascript, xml) to download instead of rendering inline on /assets.
true
ASSET_NOSNIFF
Send X-Content-Type-Options: nosniff on asset responses.
true
STRICT_TENANT_ISOLATION
(Multi-tenant only) Restrict the isTenantSpecific:false tenant-scoping bypass to the administrator role; a non-admin role marked isTenantSpecific:false is still tenant-scoped. Set false for legacy behavior.
true
OAUTH_ALLOW_UNVERIFIED_LINK
Auto-link OAuth login to an existing account when the provider's email is unverified. Default off (secure — only link verified emails; prevents takeover).
false
OAUTH_ALLOW_DIRECT_IDTOKEN
Allow client-supplied direct ID-token sign-in (POST /auth/social/signin with idToken). Default off; requires JWKS verification (Google/Apple). Redirect flow unaffected.
false
OAUTH_STATE_COOKIE_BINDING
Bind OAuth state to the browser via httpOnly cookie (CSRF). Default off (cross-site/SPA/Apple callbacks may not carry the cookie).
Response timeout (ms) per request/redirect hop for upload-from-URL (time-to-first-response, not total download time; total size is capped by MAX_UPLOAD_FILE_SIZE).
15000
ASSET_MAX_DIMENSION
Max output width/height (px) for on-the-fly image transforms; larger requests are clamped (DoS guard).
5000
ASSET_MAX_INPUT_PIXELS
Max input pixels the image decoder accepts (sharp limitInputPixels; decompression-bomb defense).
Comma-separated list of trusted frontend app origins — used for CORS and to validate OAuth redirect_url / callback targets
-
BASE_URL
Your API's own public origin, used to build the OAuth callback redirect_uri ({BASE_URL}/auth/callback/{provider}). Read at startup but not validated — if unset, OAuth callbacks silently build a relative (host-less) URL. Required whenever any social provider is enabled.
-
PUBLIC_REGISTRATION
Allow public self-serve signup via POST /auth/register. When false, that endpoint returns 403 REGISTRATION_DISABLED unless the request carries a valid invite token — invitations always continue to work.
Comma-separated list of enabled auth methods (uppercase): LOCAL, PASSKEY, TWOFACTOR, and/or any of the 35 provider ids (e.g. GOOGLE, GITHUB, DISCORD, ...). See the full 35-provider list in the SSO guide.
LOCAL
<PROVIDERID>_CLIENT_ID
OAuth client id for a given provider (e.g. GOOGLE_CLIENT_ID). A provider only activates when it's both listed in AUTH_SERVICES_ENABLED and fully credentialed.
-
<PROVIDERID>_CLIENT_SECRET
OAuth client secret for a given provider (e.g. GOOGLE_CLIENT_SECRET)
-
APPLE_TEAM_ID / APPLE_KEY_ID / APPLE_PRIVATE_KEY
Extra credentials required by Apple Sign In, alongside APPLE_CLIENT_ID/APPLE_CLIENT_SECRET
-
MICROSOFT_TENANT_ID
Tenant scoping for Microsoft (Entra ID) sign-in
common
TIKTOK_CLIENT_KEY
Extra key required by TikTok, alongside TIKTOK_CLIENT_ID/TIKTOK_CLIENT_SECRET
-
COGNITO_DOMAIN / COGNITO_REGION
Required for AWS Cognito, alongside COGNITO_CLIENT_ID/COGNITO_CLIENT_SECRET
-
WECHAT_CLIENT_ID / WECHAT_CLIENT_SECRET
Repurposed for WeChat: WECHAT_CLIENT_ID holds the WeChat appid, WECHAT_CLIENT_SECRET holds the WeChat secret
-
PASSKEY_RP_ID
WebAuthn Relying Party ID — must match your app's domain (e.g. example.com). Required for passkeys to activate.
-
PASSKEY_RP_NAME
WebAuthn Relying Party display name shown in the browser's passkey prompt. Required for passkeys to activate.
-
PASSKEY_ORIGIN
Comma-separated list of allowed origins (scheme+host+port) for WebAuthn. Required for passkeys to activate.
Brute-force limit for login/magic-link/password-reset, counted per (IP + email) pair (each account has its own budget per IP). Protects targeted brute-force; does not cap an IP's total attempts across many accounts (use a WAF/edge limit for password spraying).
10
AUTH_RATE_LIMIT_INTERVAL
Window (ms) for the auth brute-force limiter
900000
AUTH_RATE_LIMIT_DISABLED
Disable the auth brute-force limiter (auto-disabled in TEST_MODE)
false
RATE_LIMIT_BY_USER
Rate limit by user ID instead of IP (for authenticated users)
Master switch for the workflow subsystem. Default on. Set false to fully disable workflows (no item-event hooks → no per-request trigger overhead, no scheduled runs, /workflows/* → 404, no code execution). Recommended off if you don't use workflows.
true
SOCKET_ENABLED
Enable Socket.IO
false
REALTIME_ROW_LEVEL_SCOPING
Per-recipient row-level scoping for realtime broadcasts (A12): deliver a change only to subscribers whose read permission allows the row. Default off (fast room broadcast; subscribers may see other rows in their tenant). Adds per-change cost scaling with distinct subscriber roles.