Browse documentation

Generated from the settings registry in apps/server/config/settings — the one object the Studio UI, the settings service and the project-defaults service already share — by npm run docs:settings in the backend. apps/server/tests/settings-docs.unit.test.ts fails when the committed table no longer matches the registry, so this page cannot claim a field the product does not have, or omit one it does.

Each group is one row in the app_settings table, keyed by the group name; when no row exists the group resolves from its environment fallback. See settings system for how resolution, encryption and caching work, and the environment reference for the variables that seed a group before it has ever been saved.

Secret fields are encrypted with CONFIG_ENCRYPTION_KEY and returned as the sentinel __SECRET_SET__ — never in clear text.

Groups at a glance

Group keyLabelFieldsHolds a secret
server.corsSecurity · CORS2—
security.rateLimitSecurity · Rate limits6—
security.rateLimitRulesSecurity · Rate-limit rules1—
auth.tokensAuth · Token expiry2—
auth.methodsAuth · Methods4—
auth.signupAuth · Sign-up & passwords5—
auth.sessionsAuth · Sessions4—
auth.socialAuth · Social providers1yes
auth.oauth.customAuth · Custom OIDC1yes
auth.twoFactorAuth · Two-factor10—
auth.passkeyAuth · Passkey4—
auth.phoneOtpAuth · Phone (SMS)4—
auth.hooks.signUpAuth · Sign-up gate5yes
auth.hooks.accessTokenAuth · Access token claims3—
auth.hooks.sendAuth · Delivery override5yes
auth.hooks.eventsAuth · Event webhook4yes
auth.urlsAuth · URL configuration2—
auth.rateLimitsAuth · Rate limits6—
auth.thirdPartyAuth · Third-party auth1—
auth.attackProtectionAuth · Attack protection7yes
auth.apiKeyAuth · User API keys1—
auth.ssoAuth · SSO (OIDC / SAML)1—
auth.organizationAuth · Organizations4—
email.smtpEmail · SMTP6yes
phone.smsPhone / SMS7yes
email.templatesEmail templates8—
storage.providerStorage provider9yes
storage.limitsStorage · Limits2—
storage.imageTransformStorage · Image transformations2—
storage.s3Storage · S3 connection1—
storage.policiesStorage · Policies1—
push.fcmPush · Firebase4yes
push.apnsPush · APNs6yes
backup.scheduleBackups · Schedule4—
data.retentionData · Operational log retention8—
logs.retentionLogs · History and retention3—
realtime.retentionRealtime · Retention3—
realtime.limitsRealtime · Limits3—
database.sqlEditorDatabase · SQL editor1—
api.restAPI · REST2—
api.keysAPI · Keys1—
ai.assistantAI assistant7yes
git.githubGit · GitHub3yes

Every group

Security · CORS

Group key: server.cors

FieldTypeDefaultSecretNotes
origins — Allowed originstext""——
credentials — Allow credentials (cookies / auth headers)booltrue——

Security · Rate limits

Group key: security.rateLimit

Max requests per client, per scope, within the rate-limit window. Changes apply live.

FieldTypeDefaultSecretNotes
windowMin — Window (minutes)number15—The period every limit below is counted over. Changing it restarts the current window, so in-flight counters reset to zero.
global — Global (req / window / client)number1000——
auth — Auth endpointsnumber20—Every /api/auth call together. The per-kind limits (emails, SMS, sign-ins…) are auth.rateLimits.
restRead — REST read (GET)number300——
restWrite — REST write (POST/PATCH/DELETE)number120——
edge — Edge function invokesnumber60——

All six apply live. The window used to be the exception — express-rate-limit reads windowMs once at construction — so the limiters are rebuilt when it changes. Saving the group without changing the window does not rebuild, so a no-op save cannot hand every throttled caller a fresh allowance.

Security · Rate-limit rules

Group key: security.rateLimitRules

Custom rules on top of the built-in scopes. Every matching rule applies and the most restrictive wins; rules can only tighten limits. Changes apply live.

FieldTypeDefaultSecretNotes
rules — Rules (JSON array)json——Match by method / path glob / role; bucket by ip, user, apiKey, role or global.

Auth · Token expiry

Group key: auth.tokens

FieldTypeDefaultSecretNotes
accessTokenExpMin — Access token lifetime (minutes)number15——
refreshTokenExpDays — Session lifetime (days)number30——

Auth · Methods

Group key: auth.methods

FieldTypeDefaultSecretNotes
emailPassword — Email + passwordbooltrue——
magicLink — Magic linkbooltrue——
emailOTP — Email OTPbooltrue——
anonymous — Anonymous sign-insboolfalse—signInAnonymously() creates a guest user with is_anonymous = true, upgraded in place when it links an email or a provider.

Auth · Sign-up & passwords

Group key: auth.signup

Registration and password policy. Applies to new sign-ups and sign-ins after saving.

FieldTypeDefaultSecretNotes
allowNewUsers — Allow new sign-upsbooltrue—Turn off to close registration. Existing users can still sign in.
requireEmailVerification — Require email verificationboolfalse—Block sign-in until the email address is verified.
autoSignInAfterVerify — Auto sign-in after sign-upbooltrue——
minPasswordLength — Minimum password lengthnumber8——
maxPasswordLength — Maximum password lengthnumber128——

Auth · Sessions

Group key: auth.sessions

Session refresh, freshness, and revocation. Overall session length is set in Token expiry.

FieldTypeDefaultSecretNotes
revokeOnPasswordReset — Revoke all sessions on password resetbooltrue—Sign every other device out when a user resets their password.
disableRefresh — Disable sliding refreshboolfalse—When on, sessions expire at a fixed time instead of extending on use.
updateAgeHours — Refresh cadence (hours)number24—How often an active session is extended. Ignored when sliding refresh is disabled.
freshAgeMinutes — Fresh window (minutes)number0—How long after sign-in a session counts as "fresh" for sensitive actions. 0 disables the freshness requirement.

Auth · Social providers

Group key: auth.social

FieldTypeDefaultSecretNotes
providers — Providers (JSON)json—yes—

Auth · Custom OIDC

Group key: auth.oauth.custom

FieldTypeDefaultSecretNotes
providers — Custom OIDC providers (JSON array)json—yes—

Auth · Two-factor

Group key: auth.twoFactor

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
issuer — Issuer (shown in authenticator apps)text———
totpDigits — TOTP digits (6 or 8)number6——
totpPeriod — TOTP period (seconds)number30——
otpChannel — OTP second factor channelselectoff—One of off, email, sms.
otpDigits — OTP digitsnumber6——
otpPeriodMinutes — OTP validity (minutes)number3——
backupCodeCount — Backup codes countnumber10——
backupCodeLength — Backup code lengthnumber10——
trustDeviceDays — Trust device for (days)number30——

Auth · Passkey

Group key: auth.passkey

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
rpId — Relying-party ID (domain)text———
rpName — Relying-party nametext———
origin — Origintext———

Auth · Phone (SMS)

Group key: auth.phoneOtp

FieldTypeDefaultSecretNotes
enabled — Enable phone sign-inboolfalse——
otpLength — OTP lengthnumber6——
expiresIn — OTP expiry (seconds)number300——
signUpOnVerification — Create account on first verified numberbooltrue——

Auth · Sign-up gate

Group key: auth.hooks.signUp

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
emailDomainMode — Email domain ruleselectoff—One of off, allow, block.
emailDomains — Email domains (comma separated)text———
webhookUrl — Verdict webhook URLtext———
webhookSecret — Webhook signing secretpassword—yes—

Auth · Access token claims

Group key: auth.hooks.accessToken

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
includeUserFields — User fields to include (comma separated)text———
staticClaims — Static claims (JSON)json———

Auth · Delivery override

Group key: auth.hooks.send

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
email — Override email deliveryboolfalse——
sms — Override SMS deliveryboolfalse——
webhookUrl — Delivery webhook URLtext———
webhookSecret — Webhook signing secretpassword—yes—

Auth · Event webhook

Group key: auth.hooks.events

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
events — Events (comma separated path fragments)text———
webhookUrl — Event webhook URLtext———
webhookSecret — Webhook signing secretpassword—yes—

Auth · URL configuration

Group key: auth.urls

The Site URL and the redirect URLs auth flows may send users back to. Wildcards: * (within a segment), ** (anything), ? (one character).

FieldTypeDefaultSecretNotes
siteUrl — Site URLtext——The default redirect when none is given or the one given is not allowed.
redirectUrls — Redirect URLs (comma separated)text———

Auth · Rate limits

Group key: auth.rateLimits

Per-kind auth limits with GoTrue's windows. Counted per IP, except email and SMS, which are per project.

FieldTypeDefaultSecretNotes
emailSentPerHour — Emails sent per hournumber30—Every auth email (sign-up confirmation, magic link, OTP, recovery), across the whole project.
smsSentPerHour — SMS sent per hournumber30—Every auth text message, across the whole project.
tokenRefreshPer5Min — Token refreshes per 5 minutesnumber150—Access tokens minted (/token) per IP.
verifyPer5Min — Verifications per 5 minutesnumber30—OTP, magic-link, email, MFA and PKCE verifications per IP.
signInSignUpPer5Min — Sign-ups and sign-ins per 5 minutesnumber30—Per IP, all methods together.
anonymousPerHour — Anonymous sign-ins per hournumber30—Per IP.

Auth · Third-party auth

Group key: auth.thirdParty

JWTs from Clerk, Firebase Auth, Auth0, AWS Cognito or WorkOS, accepted by the data API. The role claim picks the Postgres role (anon, else authenticated; service_role is refused).

FieldTypeDefaultSecretNotes
providers — Providers (JSON array)json———

Auth · Attack protection

Group key: auth.attackProtection

CAPTCHA on the auth endpoints and on any other route you choose, and a leaked-password check.

FieldTypeDefaultSecretNotes
captchaEnabled — Enable CAPTCHA protectionboolfalse—Clients must then send a token on every guarded call: options.captchaToken on auth calls, the x-captcha-response header elsewhere.
captchaProvider — CAPTCHA providerselecthcaptcha—One of hcaptcha, turnstile.
captchaSecret — CAPTCHA secretpassword—yes—
captchaSiteKey — Site key (hCaptcha, optional)text——When set, hCaptcha also checks the token was issued for this site key.
captchaAuthEndpoints — Guarded auth endpointsjson["/sign-up/email","/sign-in/email","/sign-in/anonymous","/sign-in/magic-link","/email-otp/send-verification-otp","/email-otp/request-password-reset","/phone-number/send-otp","/request-password-reset"]—Which auth calls need a token. Any of /sign-up/email, /sign-in/email, /sign-in/anonymous, /sign-in/magic-link, /email-otp/send-verification-otp, /email-otp/request-password-reset, /phone-number/send-otp, /request-password-reset. All of them by default, as in Supabase.
captchaRoutes — Other guarded routesjson[]—Any other route: a table's REST API (/rest/v1/<table>), an edge function (/api/edge/<name>), storage. * matches any run of characters. No methods means every method. Server-side callers must send a token too.
leakedPasswordProtection — Prevent use of leaked passwordsboolfalse—Rejects passwords found in HaveIBeenPwned. Only the first 5 characters of the SHA-1 hash are sent.

Auth · User API keys

Group key: auth.apiKey

Personal API keys each user mints through the auth API. Not the project keys (api.keys).

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——

Auth · SSO (OIDC / SAML)

Group key: auth.sso

The single switch for OIDC / SAML SSO, including per-organization SSO. When on, it mounts the SSO plugin and its /api/auth/sso/* endpoints. When off, no provider can be registered or used. The provider a user reaches is tenant data in ssoProvider records, not an organization setting here.

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse—Required for all SSO, including per-organization SSO. Auth · Organizations has no SSO switch of its own.

Auth · Organizations

Group key: auth.organization

End-user organizations (Better Auth organization plugin): creation, teams, and member limits. SSO is not configured here. Enable it in Auth · SSO, the only switch that governs SSO.

FieldTypeDefaultSecretNotes
enabled — Enabledbooltrue——
allowUserToCreateOrganization — Users can create orgsbooltrue——
teamsEnabled — Teams inside organizationsboolfalse—Adds Better Auth team sub-groups and their endpoints. This is unrelated to SSO; org admins register identity providers at runtime.
maxMembers — Maximum members per organizationnumber0—0 = unlimited. Applies when a member is added directly, when an invitation is accepted, and when SSO auto-provisions a member.

Email · SMTP

Group key: email.smtp

FieldTypeDefaultSecretNotes
host — SMTP hosttext——Required.
port — Portnumber465—Required.
username — Usernametext——Required.
password — Passwordpassword—yes—
from — From addresstext———
secure — Secure (TLS)booltrue——

Phone / SMS

Group key: phone.sms

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
provider — Providertext———
accountSid — Account SIDtext———
authToken — Auth tokenpassword—yes—
from — From numbertext———
messagingServiceSid — Messaging Service SID (optional)text———
testNumbers — Test numbers (bypass real SMS)text——Comma-separated phone:code pairs. Matching numbers skip Twilio and accept the fixed code, for app-store review and e2e tests.

Email templates

Group key: email.templates

Customise transactional auth emails. Code templates use {{code}}; link templates use {{url}} (rendered as a button/link). {{appName}} and {{email}} are always available.

FieldTypeDefaultSecretNotes
verificationSubject — Email OTP · verification subjecttextVerify your email——
verificationBody — Email OTP · verification bodytext——Requires {{code}}. Allowed: {{appName}}, {{code}}, {{email}}
recoverySubject — Password reset subjecttextReset your password——
recoveryBody — Password reset bodytext——Requires {{code}}. Allowed: {{appName}}, {{code}}, {{email}}
magicLinkSubject — Magic-link subjecttextYour sign-in link——
magicLinkBody — Magic-link bodytext——Requires {{url}}. Allowed: {{appName}}, {{url}}, {{email}}
verifyLinkSubject — Verification-link subjecttextVerify your email——
verifyLinkBody — Verification-link bodytext——Requires {{url}}. Allowed: {{appName}}, {{url}}, {{email}}

Storage provider

Group key: storage.provider

FieldTypeDefaultSecretNotes
driver — Driverselectlocal—One of local, s3.
staticPath — Local static pathtextuploads——
userPath — Local user pathtextusers——
s3Endpoint — S3 endpointtext———
s3Region — S3 regiontextus-east-1——
s3AccessKeyId — S3 access key IDtext———
s3SecretAccessKey — S3 secret access keypassword—yes—
s3Bucket — S3 buckettextuploads——
s3PublicUrl — S3 public URLtext———

Storage · Limits

Group key: storage.limits

Upload size and type constraints. Max size is also capped by the server MAX_UPLOAD_MB.

FieldTypeDefaultSecretNotes
maxUploadBytes — Max upload size (bytes)number0—0 uses the server default (MAX_UPLOAD_MB). A positive value is additionally capped to it.
allowedMimeTypes — Allowed MIME typestext——Comma-separated. Blank allows all. Wildcards like image/* are supported.

Storage · Image transformations

Group key: storage.imageTransform

Resize and convert images on the fly through /storage/v1/render/image.

FieldTypeDefaultSecretNotes
enabled — Enable image transformationsbooltrue—When off, every render URL answers 403 and the original object is still downloadable as usual.
maxSourceBytes — Largest source image (bytes)number26214400—Images above this size are refused rather than decoded. 25 MB, like Supabase, by default.

Storage · S3 connection

Group key: storage.s3

An S3-compatible endpoint at /storage/v1/s3, authenticated with S3 access keys.

FieldTypeDefaultSecretNotes
enabled — Enable the S3 protocolbooltrue—When off, every S3 request is refused. Access keys are kept and work again once it is back on.

Storage · Policies

Group key: storage.policies

Authorize storage with PostgreSQL row level security instead of the built-in owner rule.

FieldTypeDefaultSecretNotes
enabled — Use RLS policies for storageboolfalse—When on, every read and write is decided by the policies on storage.files, the same way table access is. The migration installs policies reproducing the built-in behaviour, so turning this on changes nothing until you write your own. When off, the built-in rule applies: an object is readable if it is public or if you own it.

Off by default because turning it on changes who can read every object in the project, and an upgrade does not get to do that silently. The migration installs policies reproducing the built-in behaviour, so switching over changes nothing until you write your own.

Push · Firebase

Group key: push.fcm

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
projectId — Project IDtext———
clientEmail — Client emailtext———
privateKey — Private keypassword—yes—

Push · APNs

Group key: push.apns

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
key — APNs keypassword—yes—
keyId — Key IDtext———
teamId — Team IDtext———
bundleId — Bundle IDtext———
production — Productionboolfalse——

Backups · Schedule

Group key: backup.schedule

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
cron — Cron expressiontext0 3 * * *——
retention — Retention (keep newest N)number7——
offsite — Offsite upload to S3boolfalse——

Data · Operational log retention

Group key: data.retention

FieldTypeDefaultSecretNotes
enabled — Enabledbooltrue——
cron — Cron expressiontext15 4 * * *——
webhookDeliveryDays — Webhook delivery retention (days)number30——
edgeFunctionLogDays — Edge function log retention (days)number30——
jobRunDays — Scheduler run history (days)number30—Rows in platform.job_runs older than this are deleted. Every scheduled job writes one per run, so this is the fastest-growing operational table.
authAuditLogDays — Auth audit log retention (days)number90—Rows in auth.audit_log_entries (Authentication → Audit Logs) older than this are deleted.
batchSize — Rows per batchnumber500——
maxBatchesPerRun — Maximum batches per runnumber20——

Logs · History and retention

Group key: logs.retention

Keep log lines in the database so the Logs screen can look further back than the in-memory buffer and survive a restart. Retention is applied by the data-retention job.

FieldTypeDefaultSecretNotes
enabled — Store logs in the databasebooltrue—Off keeps the in-memory buffer only: history is capped by CONSOLE_LOG_BUFFER_SIZE and lost on restart.
retentionDays — Keep logs for (days)number7—Lines older than this are deleted on the next data-retention run.
maxRows — Maximum stored linesnumber2000000—Hard ceiling regardless of age; the oldest lines above it are deleted. 0 disables the cap.

Realtime · Retention

Group key: realtime.retention

Prune processed realtime outbox rows. Only completed/failed (terminal) rows are removed; pending and processing rows are never touched.

FieldTypeDefaultSecretNotes
enabled — Enabledbooltrue——
completedDays — Keep delivered events (days)number7—Completed realtime events, and messages sent with realtime.send, older than this are purged.
failedDays — Keep failed events (days)number30—Failed realtime events are kept longer for debugging.

Realtime · Limits

Group key: realtime.limits

Constraints applied when a client subscribes to a realtime topic.

FieldTypeDefaultSecretNotes
enablePostgresChanges — Enable postgres_changesbooltrue—When off, database-change subscriptions are ignored. Broadcast and presence still work.
maxChannelsPerClient — Max channels per clientnumber100—Reject further channel subscriptions from a single connection past this count.
privateOnly — Private channels onlyboolfalse—Refuse public channels. Every channel must be joined with private: true and is authorized by the policies on realtime.messages.

Database · SQL editor

Group key: database.sqlEditor

What the Studio SQL editor may run. Changes apply to the next query.

FieldTypeDefaultSecretNotes
allowWrites — Allow writes from the SQL editorbooltrue—On, the editor runs anything, as the database owner. Off, every statement runs in a Postgres READ ONLY transaction and INSERT, UPDATE, DELETE and DDL are refused.

API · REST

Group key: api.rest

Limits for the auto-generated REST API. Changes apply on the next request.

FieldTypeDefaultSecretNotes
maxRows — Max rows per requestnumber1000—Upper bound on rows a single GET returns. The parser also enforces a hard ceiling of 1000.
rpcSecurityDefiner — Exposed SECURITY DEFINER functionstext""—Comma-separated function names reachable over /rest/v1/rpc/. A SECURITY DEFINER function runs as its owner and bypasses the caller's row-level security, so each one must be listed here explicitly. Empty means none are exposed.

Function names are stored verbatim: they are matched against pg_proc.proname, and a quoted CREATE FUNCTION "MyFn" really is stored as MyFn, so case is not folded. Entries longer than Postgres' 63-byte identifier limit, or carrying control characters, are rejected on save.

API · Keys

Group key: api.keys

Whether a project API key is required to reach the REST API.

FieldTypeDefaultSecretNotes
requireApiKey — Require a project API keyboolfalse—When on, every REST request must carry a valid publishable or secret key in the apikey header. Off by default so an app running against an older version keeps working across an upgrade. Turn it on once your clients send the key: revoking a key then cuts that caller off without touching a single policy.

Off by default so an app running against an older version keeps working across an upgrade. Turn it on once your clients send the key: revoking a key then cuts that caller off without touching a single policy. The keys themselves are not settings — they live in their own table and are managed from Project Settings → API keys or motherbase keys.

AI assistant

Group key: ai.assistant

Bring your own model key. The assistant runs server side and can only do what your account can do.

FieldTypeDefaultSecretNotes
enabled — Enabledboolfalse——
provider — Providerselectanthropic—One of anthropic, openai, gemini, deepseek, qwen, glm, moonshot, mistral, xai, groq, openrouter, compatible.
model — Modeltext——Any model id the provider accepts. Leave blank to use the provider default.
apiKey — API keypassword—yes—
baseUrl — Base URLtext——Leave blank to use the provider's own endpoint. Required for a custom OpenAI-compatible server (Ollama, vLLM, LiteLLM).
maxSteps — Maximum tool steps per messagenumber12——
autoApproveWrites — Run write actions without confirmationboolfalse—Off by default. When off, the assistant proposes changes and you press Run.

Git · GitHub

Group key: git.github

A GitHub OAuth App (Settings → Developer settings → OAuth Apps). Its Authorization callback URL must be exactly the callback URL below.

FieldTypeDefaultSecretNotes
clientId — Client IDtext———
clientSecret — Client secretpassword—yes—
callbackUrl — Authorization callback URLtext——The Studio page GitHub returns the browser to. Its origin is also where the push webhook is delivered.

Where to read more