ObjectStackObjectStack

Environment Variables

Canonical list of OS_* environment variables read by the ObjectStack runtime, CLI, and built-in plugins.

Environment Variables

All ObjectStack-owned environment variables use the OS_ prefix. Variables are read at startup unless noted otherwise. Boolean variables accept true / false (case-insensitive); flag-style variables also accept 1 / 0 where noted.

Legacy names. Pre-1.0 unprefixed names (PORT, DATABASE_URL, BETTER_AUTH_SECRET, …) still work this release and emit a one-shot deprecation warning. See Legacy aliases at the bottom of this page. Industry-standard third-party names (NODE_ENV, HOME, OPENAI_API_KEY, TURSO_*, OAuth *_CLIENT_ID / *_CLIENT_SECRET, RESEND_API_KEY, POSTMARK_TOKEN, AI_GATEWAY_*, SMTP_*) are not renamed and are read as-is by their respective libraries.


Runtime & Server

VariableTypeDefaultDescription
OS_PORTnumber3000HTTP listener port for os serve / os dev / os start. Resolution: --portOS_PORTPORT3000.
OS_HOMEpath$HOME/.objectstackObjectStack config / state directory.
OS_MODEenumstandaloneRuntime mode. standalone | cloud.
OS_BOOT_EMPTYflag0When 1, boot the kernel with no metadata artifact (CLI internal).
OS_MIGRATE_AND_EXITflag0When 1, run pending migrations and exit (suitable for one-shot jobs).
OS_DISABLE_CONSOLEflag0When 1, do not mount the Console portal under /_console.
OS_EAGER_SCHEMASflag0When 1, eagerly materialise all object schemas at boot (slower start, faster first request).
OS_SKIP_SCHEMA_SYNCflag0When 1, skip the implicit db:sync on boot. Use after running migrations manually.

Port conflicts behave differently by mode. In dev (os dev, or NODE_ENV=development) a busy port auto-hops to the next free one (up to +100) and the banner prints the actual bound port. In production (os start) a busy port is a hard error (exit 1) — it never silently drifts, because a shifted port breaks reverse-proxy upstreams, OS_AUTH_URL callbacks, and OS_TRUSTED_ORIGINS (CORS). Pin the port explicitly in production (OS_PORT=8080 os start) and keep OS_AUTH_URL / OS_TRUSTED_ORIGINS in sync with it.


Database & Storage

VariableTypeDefaultDescription
OS_DATABASE_URLurlDatabase connection string (e.g. file:./data.sqlite, postgres://…, mongodb://…, memory://). libsql:// (Turso) is not supported.
OS_DATABASE_DRIVERenuminferredForce a specific driver when the URL is ambiguous. memory | sqlite | sqlite-wasm | postgres | mongodb.
OS_STORAGE_ROOTpath./.objectstack/data/uploadsRoot directory for the local file storage adapter, relative to the process cwd (used by os serve's default storage capability wiring).
OS_ARTIFACT_PATHpathPath or http(s):// URL to a compiled objectstack.json artifact to boot the kernel from.

Secrets & Clustering

VariableTypeDefaultDescription
OS_SECRET_KEYstring32-byte master key (64 hex chars or base64) for sys_secret encryption — encrypted settings, secret fields, datasource credentials. Required for containerized or multi-node deployments; on a single durable host os start mints and persists a dev key instead. See Deployment Modes.
OS_DEV_CRYPTO_KEYstringDevelopment convenience crypto key, consulted after OS_SECRET_KEY. Do not use in production.
OS_CLUSTER_DRIVERstringmemoryCluster coordination driver id. When set to anything other than memory, the runtime treats the deployment as multi-node (and requires OS_SECRET_KEY). Non-memory drivers are opt-in sibling packages (e.g. redis via @objectstack/service-cluster-redis) — see Cluster.
OS_REDIS_URLurlConnection URL passed to a non-memory cluster driver (e.g. OS_CLUSTER_DRIVER=redis).

Authentication

VariableTypeDefaultDescription
OS_AUTH_URLurlhttp://localhost:<OS_PORT>Public base URL of the auth server. Required behind a proxy or in production.
OS_AUTH_SECRETstringauto-generated (dev)Secret used to sign sessions and cookies. Required in production.
OS_AUTH_TWO_FACTORbooleanfalseEnable the low-level better-auth two-factor plugin. Keep disabled unless your UI handles enrollment, login challenge, and backup-code recovery.
OS_DISABLE_SIGNUPbooleanfalseWhen true, block new email/password sign-ups. The very first user can still sign up to bootstrap admin.
OS_AUTH_EMAIL_PASSWORD_ENABLEDbooleansettings defaultSettings env override for auth.email_password_enabled. Controls local email/password login.
OS_AUTH_SIGNUP_ENABLEDbooleansettings defaultSettings env override for auth.signup_enabled. Takes precedence over UI settings and is preferred over OS_DISABLE_SIGNUP.
OS_AUTH_REQUIRE_EMAIL_VERIFICATIONbooleansettings defaultSettings env override for auth.require_email_verification.
OS_AUTH_GOOGLE_ENABLEDbooleansettings defaultSettings env override for auth.google_enabled. Requires Google OAuth credentials from Settings or env.
GOOGLE_CLIENT_IDstringDeployment-level Google OAuth client id for the open-source Google login implementation.
GOOGLE_CLIENT_SECRETstringDeployment-level Google OAuth client secret for the open-source Google login implementation.
OS_MULTI_ORG_ENABLEDbooleanfalseWhen true, expose organization creation/switching UI. When false, run in single-tenant mode.
OS_OIDC_PROVIDER_ENABLEDbooleanfalseWhen true, expose this instance as an OIDC identity provider.
OS_COOKIE_DOMAINstringCookie domain for cross-subdomain session sharing (e.g. .example.com).
OS_TRUSTED_ORIGINScsvComma-separated list of origins permitted for auth callbacks / CSRF.
OS_TERMS_URLurlURL shown next to the "Terms of Service" link on the sign-up form. Empty string hides the link.
OS_PRIVACY_URLurlURL shown next to the "Privacy Policy" link on the sign-up form. Empty string hides the link.

Auth settings precedence:

  1. Environment variables win over values saved in the Setup UI.
  2. OS_AUTH_<SETTING_KEY> settings env vars are the canonical form for settings-backed auth controls.
  3. Existing deployment toggles such as OS_AUTH_TWO_FACTOR and OS_DISABLE_SIGNUP remain supported.
  4. Google credentials can be saved in Setup → Authentication. google_client_secret is encrypted at rest.
  5. GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET remain supported for deployment-level Google OAuth configuration.

CORS

VariableTypeDefaultDescription
OS_CORS_ENABLEDbooleantrueEnable CORS middleware.
OS_CORS_ORIGINcsv*Allowed origins (comma-separated, or *).
OS_CORS_CREDENTIALSbooleantrueAllow credentialed cross-origin requests.
OS_CORS_MAX_AGEnumber86400Preflight cache TTL in seconds.

Branding (single-tenant)

VariableTypeDefaultDescription
OS_PRODUCT_NAMEstringObjectStackProduct name shown in the UI chrome and emails.
OS_PRODUCT_SHORT_NAMEstringOSShort name used in compact UI surfaces (favicons, mobile titles).
OS_APP_NAMEstringApplication name surfaced to auth providers (used as the OAuth app display name).

Email

VariableTypeDefaultDescription
OS_EMAIL_PROVIDERenumlogTransport. log | resend | postmark. log (default) prints to stdout without sending. Real SMTP delivery requires the separate @objectstack/plugin-mail-smtp package.
OS_EMAIL_API_KEYstringAPI key for resend / postmark.
OS_EMAIL_FROMemailDefault From: address.
OS_EMAIL_RETRIESnumber3Retry count for transient send failures.

No SMTP transport ships in the open-core runtime — OS_EMAIL_PROVIDER only materialises log, resend, or postmark. Real SMTP delivery requires the separate @objectstack/plugin-mail-smtp package, which reads its own SMTP settings (configured in Settings → Mail or via the plugin's constructor options).


AI

These variables configure the ObjectOS in-product AI runtime, which is not part of the open-source framework. The open-source framework has no in-UI AI runtime to configure: it exposes AI through @objectstack/mcp (BYO-AI), where the model and provider are configured in your own MCP client (Claude, Cursor, a local model, …). See the AI Capabilities guide.

VariableTypeDefaultDescription
AI_GATEWAY_MODELstringVercel AI Gateway model id (for example openai/gpt-4.1-mini or anthropic/claude-sonnet-4-5). When set, the AI service boots with the gateway adapter before trying direct providers.
AI_GATEWAY_API_KEYstringVercel AI Gateway API key. Required by the gateway SDK for real gateway calls; by itself it does not select the gateway adapter. Pair it with AI_GATEWAY_MODEL.
OPENAI_API_KEYstringSelects the direct OpenAI adapter when no gateway model is configured. Default model: gpt-4o.
ANTHROPIC_API_KEYstringSelects the direct Anthropic adapter when gateway and OpenAI are not configured. Default model: claude-sonnet-4-20250514.
GOOGLE_GENERATIVE_AI_API_KEYstringSelects the direct Google Gemini adapter when gateway, OpenAI, and Anthropic are not configured. Default model: gemini-2.0-flash.
OS_AI_MODELstringprovider defaultOverrides the model id for direct OpenAI / Anthropic / Google provider detection. Does not override AI_GATEWAY_MODEL; gateway model ids already include the provider prefix.
OS_AI_ACTION_API_BASE_URLurlBase URL prepended to relative type: 'api' action targets exposed as AI tools. Without this or a plugin apiActionBaseUrl, relative API actions are skipped for AI exposure.
OS_AI_PROVIDERenumSettings override for the AI provider. Supported values include gateway, openai, anthropic, google, deepseek, dashscope, cloudflare, siliconflow, and openrouter. When set, it locks the Settings UI value.
OS_AI_GATEWAY_MODELstringSettings override for the Vercel AI Gateway model id. Use with OS_AI_PROVIDER=gateway.
OS_AI_GATEWAY_API_KEYstringSettings override for the Vercel AI Gateway API key. Use with OS_AI_PROVIDER=gateway.
OS_AI_OPENAI_BASE_URLurlSettings override for the OpenAI-compatible chat base URL. Use with OS_AI_PROVIDER=openai for Azure, local gateways, or third-party OpenAI-shaped APIs.
OS_AI_OPENAI_API_KEYstringSettings override for the OpenAI-compatible API key. Stored only in env; the Settings UI cannot overwrite it while present.
OS_AI_OPENAI_MODELstringgpt-4oSettings override for the OpenAI-compatible chat model id.
OS_AI_ANTHROPIC_API_KEYstringSettings override for the Anthropic API key. Use with OS_AI_PROVIDER=anthropic.
OS_AI_ANTHROPIC_MODELstringclaude-sonnet-4-20250514Settings override for the Anthropic model id.
OS_AI_GOOGLE_API_KEYstringSettings override for the Google Generative AI API key. Use with OS_AI_PROVIDER=google.
OS_AI_GOOGLE_MODELstringgemini-2.0-flashSettings override for the Google model id.
OS_AI_<PROVIDER>_API_KEYstringSettings override for preset OpenAI-compatible providers, for example OS_AI_DEEPSEEK_API_KEY, OS_AI_DASHSCOPE_API_KEY, OS_AI_SILICONFLOW_API_KEY, or OS_AI_OPENROUTER_API_KEY.
OS_AI_<PROVIDER>_MODELstringprovider defaultSettings override for preset provider model ids, for example OS_AI_DEEPSEEK_MODEL=deepseek-chat.

The boot-time LLM adapter priority is:

  1. Explicit AIServicePlugin({ adapter }) or per-plugin gatewayModel option.
  2. AI_GATEWAY_MODEL using @ai-sdk/gateway.
  3. OPENAI_API_KEY using @ai-sdk/openai.
  4. ANTHROPIC_API_KEY using @ai-sdk/anthropic.
  5. GOOGLE_GENERATIVE_AI_API_KEY using @ai-sdk/google.
  6. MemoryLLMAdapter echo mode when no real provider is configured.

After boot, if the Settings service is mounted, the ObjectOS AI runtime reads the ai Settings namespace and swaps the adapter when the provider comes from env or a stored Settings UI value. The manifest default provider=memory is ignored so it does not mask boot-time auto-detection; an explicit OS_AI_PROVIDER=memory or stored UI value does switch the runtime back to memory. Settings values resolve as:

env (`OS_<NAMESPACE>_<KEY>`) > stored Settings UI value > default

That means OS_AI_PROVIDER=openai plus OS_AI_OPENAI_BASE_URL=... wins over both the Settings UI and the boot-time provider auto-detection. ObjectStack does not read unprefixed settings override names such as AI_PROVIDER or AI_OPENAI_BASE_URL.

For example, a third-party OpenAI-compatible provider can be deployment-locked without using the Settings UI:

OS_AI_PROVIDER=openai
OS_AI_OPENAI_API_KEY=sk-...
OS_AI_OPENAI_MODEL=your-model
OS_AI_OPENAI_BASE_URL=https://your-provider.example.com/v1

Provider credentials keep their upstream names. ObjectStack does not rename OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, or AI_GATEWAY_* to OS_*.

OpenAI-compatible base URLs. Use OS_AI_OPENAI_BASE_URL with OS_AI_PROVIDER=openai, configure the same fields in Settings → AI, or pass an explicit adapter in code. Do not rely on OPENAI_BASE_URL as a platform-level environment variable.


MCP Server

Enable this to make the app you built AI-operable: with the MCP server on, an MCP client — Claude Code, Claude Desktop, Cursor, or a local model — connects to your running app and gets a generated tool surface over your objects and actions (query_records, run_action, …), bound to the caller's principal and governed by the same RBAC / RLS as the Console. No custom tooling, no separate API. See Actions as Tools for the tool set.

os start                                # MCP is served at /api/v1/mcp by default
OS_MCP_SERVER_ENABLED=false os start    # opt out of the MCP surface
OS_MCP_SERVER_ENABLED=true os start     # additionally auto-start the stdio transport
VariableTypeDefaultDescription
OS_MCP_SERVER_ENABLEDbooleantrueThe MCP HTTP surface (/api/v1/mcp) is a core capability and defaults on. Set false to disable it. An explicit true additionally auto-starts the long-lived stdio transport at boot.
OS_MCP_SERVER_NAMEstringobjectstackServer name advertised to MCP clients.
OS_MCP_SERVER_TRANSPORTenumstdiostdio | http. Use http (Streamable HTTP) for a remote client; stdio for a local one.

Pinyin recall for $search (ADR-0098): with the switch on, every object's display/name field gets a hidden, platform-maintained companion column storing full pinyin + initials ("张伟" → "zhangwei zw"), so lookup pickers, list quick-search and ⌘K match zhangwei / zw against CJK names — transparently, with no client or object changes.

os start                                  # auto-on when the stack's i18n config lists any zh-* locale
OS_SEARCH_PINYIN_ENABLED=true os start    # force on regardless of locales
OS_SEARCH_PINYIN_ENABLED=false os start   # force off (e.g. a zh-locale stack that doesn't want the extra column)
VariableTypeDefaultDescription
OS_SEARCH_PINYIN_ENABLEDbooleanlocale-derivedPinyin search recall. When unset, the default derives from the stack's configured locales (i18n.defaultLocale / supportedLocales / fallbackLocale): any zh-* locale turns it on; an explicit value always wins. Gates both the compile-time __search companion column and the plugin-pinyin-search populate hooks, so there is no half-state. Off ⇒ no extra column, and pinyin-pro is never loaded.

Coverage includes sys_user — the people picker finds users by pinyin with no per-object configuration. Rows that predate the switch are backfilled automatically on the first boot after it turns on (paged, idempotent); for runtime bulk imports that bypassed write hooks, rebuildSearchCompanion (from @objectstack/plugin-pinyin-search) recomputes the column on demand. See Queries → Pinyin recall.


Marketplace & Metadata

VariableTypeDefaultDescription
OS_MARKETPLACE_CACHEenumonoff disables the in-memory marketplace listing cache.
OS_MARKETPLACE_PUBLIC_BASE_URLurlPublic base URL of the marketplace registry (proxied from this runtime when set).
OS_METADATA_WRITABLEcsv— (none)Comma-separated metadata type names (e.g. hook,validation) granted a runtime escape hatch that treats them as allowOrgOverride: true, letting artifact-backed items of those protected types be overridden per-org outside their static registry declaration. See ADR-0005.

Multi-tenant / Cloud control plane

These variables are only meaningful when running in OS_MODE=cloud or against the hosted ObjectOS Cloud control plane.

VariableTypeDefaultDescription
OS_BASE_URLurlPublic base URL of this runtime, used in generated webhooks and links.
OS_ROOT_DOMAINstringRoot domain for multi-tenant subdomain routing (e.g. example.com).
OS_ORGANIZATION_IDstringPin the runtime to a single organization id (per-process scope).
OS_ENVIRONMENT_IDstringPin the runtime to a single environment id (per-process scope).
OS_CLOUD_URLurlhttps://cloud.objectos.aiBase URL of the cloud control plane the CLI / runtime talks to. Set to off / local / none / disabled to disable cloud.
OS_CLOUD_API_KEYstringShared secret authenticating runtime → cloud SSO handoffs.
OS_CLI_CLIENT_IDstringOAuth client id used by os login.
OS_TOKENstringPersonal access token used by the CLI in non-interactive contexts (CI).
OS_PLATFORM_SSObooleantrueWhen false, fall back to local auth instead of the platform SSO handshake.
OS_PROVISION_SYNCflag0When 1, force synchronous provisioning of artifact kernels (slower boot, deterministic).
OS_RUNTIME_PORTnumberPort the cloud control plane uses to reach this runtime (distinct from public OS_PORT).
OS_PREVIEW_MODEenumPreview deployment routing mode.
OS_PREVIEW_BASE_DOMAINScsvComma-separated base domains used to resolve preview hostnames.

Observability

VariableTypeDefaultDescription
OS_OBS_EXPORTERenumnoopOpenTelemetry exporter. noop | console | json | otlp. noop (default) imposes no runtime cost.
OS_OBS_SERVICE_NAMEstringobjectstackservice.name resource attribute.
OS_OBS_DEPLOYMENT_ENVstringproductiondeployment.environment resource attribute.
OS_OTLP_ENDPOINTurlOTLP/HTTP collector endpoint. Required when OS_OBS_EXPORTER=otlp.
OS_OTLP_HEADERScsvComma-separated key=value pairs added to every OTLP export.
OS_OTLP_FLUSH_MSnumber10000OTLP batch flush interval.

Tuning (advanced)

VariableTypeDefaultDescription
OS_KERNEL_CACHE_SIZEnumber32Max in-memory artifact kernels per process (cloud mode).
OS_KERNEL_TTL_MSnumber900000Idle TTL for cached kernels in ms.
OS_ENV_CACHE_TTL_MSnumber300000Env-record cache TTL in ms.
OS_ARTIFACT_CACHE_TTL_MSnumber300000Artifact-record cache TTL in ms.
OS_ARTIFACT_FETCH_TIMEOUT_MSnumber60000Timeout for remote artifact fetches. Only a positive value is honored — an unset, non-numeric, or 0 value falls back to the 60s default (pass fetchTimeoutMs: 0 in artifactSource config to actually disable the timeout).
OS_INLINE_SEED_BUDGET_MSnumber8000Time budget for synchronous seed execution at boot before deferring to a worker.
OS_TENANT_AUDITflag1Set to 0 to silence the tenant-isolation audit warnings emitted by the SQL driver.

Legacy aliases

Some env vars accept a legacy alias for compatibility. Ecosystem-standard names (e.g. DATABASE_URL, AUTH_SECRET, BETTER_AUTH_*, PORT, CORS_*, MCP_SERVER_*) are permanently accepted and no longer warn. ObjectStack's own former names are deprecated — prefer the canonical OS_*.

Removed in 11 (rename required): OS_MULTI_TENANTOS_MULTI_ORG_ENABLED, AUTH_BASE_URL/OS_AUTH_BASE_URLOS_AUTH_URL.

CanonicalLegacy
OS_PORTPORT
OS_DATABASE_URLDATABASE_URL
OS_AUTH_URLBETTER_AUTH_URL
OS_AUTH_SECRETBETTER_AUTH_SECRET, AUTH_SECRET
OS_ROOT_DOMAINROOT_DOMAIN
OS_CORS_ENABLEDCORS_ENABLED
OS_CORS_ORIGINCORS_ORIGIN
OS_CORS_CREDENTIALSCORS_CREDENTIALS
OS_CORS_MAX_AGECORS_MAX_AGE
OS_AI_MODELAI_MODEL
OS_MCP_SERVER_ENABLEDMCP_SERVER_ENABLED
OS_MCP_SERVER_NAMEMCP_SERVER_NAME
OS_MCP_SERVER_TRANSPORTMCP_SERVER_TRANSPORT
OS_METADATA_WRITABLEOBJECTSTACK_METADATA_WRITABLE
OS_HOMEOBJECTSTACK_HOME
OS_DEV_CRYPTO_KEYOBJECTSTACK_DEV_CRYPTO_KEY

On this page