284 lines
17 KiB
Bash
284 lines
17 KiB
Bash
# SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
||
# Every variable this app reads, what it is for, who sets it on ConusAI Cloud, and what a local run
|
||
# puts here. Nothing is read at build time, so one image serves every environment (there is no
|
||
# NEXT_PUBLIC_* value in this file by design, spec §6.4). A test fails when a variable the code reads
|
||
# is missing from this file (test/env-example.test.ts).
|
||
#
|
||
# Two ways to run it locally, and they need different things from this file:
|
||
#
|
||
# pnpm dev
|
||
# needs NO .env at all, and reads none. It starts Postgres in Docker, the fake platform, the
|
||
# migrate job, the demo data, the worker and the web shell on this machine, with the values it
|
||
# prints. A value you want different is a variable in your shell, not in this file: DEV_WEB_PORT,
|
||
# DEV_PLATFORM_PORT and DEV_POSTGRES_PORT move the ports; POSTGRES_URL, POSTGRES_READER_URL and
|
||
# POSTGRES_MIGRATE_URL (all three) use a Postgres of your own.
|
||
#
|
||
# cp .env.example .env && docker compose -f compose.yaml -f compose.dev.yaml up --build
|
||
# needs this file as it is, plus AUTH_SESSION_SECRET (below). The same stack as containers.
|
||
#
|
||
# On ConusAI Cloud the platform injects the "platform" and "Postgres" groups, and you set the
|
||
# "sign-in" group and anything under "this app" in the project's settings.
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# The platform (injected into every service; @conusai-kit/platform parses it at boot and the app
|
||
# refuses to start without the first four, naming the one that is missing)
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# The platform API, ending in /api. The AI gateway, OCR, Blob, audit and usage are all reached here.
|
||
CONUSAI_API_URL=http://platform:4010/api
|
||
# The deployment token. A secret: never in an image, a log or an error message.
|
||
CONUSAI_API_TOKEN=dev-token
|
||
# The project this deployment is.
|
||
CONUSAI_PROJECT_ID=1
|
||
# The ConusAI organization that owns the deployment: usage is metered against it. Required in
|
||
# production; a development run uses "dev".
|
||
CONUSAI_ORG_ID=dev
|
||
# Optional business modules require the real platform-injected numeric organization and
|
||
# environment IDs. They refuse service dispatch when these are missing; other app pages stay usable.
|
||
CONUSAI_ENVIRONMENT_ID=
|
||
# Reserved optional Cloud identity from the authenticated installed release policy.
|
||
# Empty stays unavailable. Standalone adoption must verify the descriptor independently.
|
||
# These identify Cloud, while CONUSAI_RELEASE below identifies this application's source.
|
||
CONUSAI_PLATFORM_RELEASE_DESCRIPTOR=
|
||
CONUSAI_PLATFORM_SOURCE_COMMIT=
|
||
# Platform-injected organization slug for slug-scoped usage billing. The app also applies this organization's
|
||
# branding from the platform (brand-kit BK12); empty, the app keeps the kit's default theme.
|
||
CONUSAI_ORG_SLUG=
|
||
# Platform-injected workspace and project slugs: the knowledge service's routes name them, with the
|
||
# organization's. A development run that uses knowledge against the fake platform sets all three.
|
||
CONUSAI_WORKSPACE_SLUG=
|
||
CONUSAI_PROJECT_SLUG=
|
||
# The address the app is served at, with no trailing slash. The sign-in redirect URIs derive from it.
|
||
CONUSAI_PUBLIC_URL=http://127.0.0.1:3000
|
||
# The release being run (the commit), reported with every error and log line.
|
||
CONUSAI_RELEASE=dev
|
||
# production, preview or a named environment. Without it: production in a production run, else development.
|
||
CONUSAI_ENVIRONMENT=
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# Convex profile only. The backup sidecar needs an admin key; keep this secret out of source control.
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# The Convex provider injects these exact names into linked services. The admin key is server-only:
|
||
# it deploys app functions and lets the Next BFF attach trusted identities; never prefix it NEXT_PUBLIC.
|
||
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:53210
|
||
CONVEX_SELF_HOSTED_ADMIN_KEY=
|
||
# For local development, generate the key
|
||
# with `docker exec <backend-container> ./generate_admin_key.sh`.
|
||
# Scheduled export cadence and number of newest archives retained. Defaults: 24 hours and 30.
|
||
CONVEX_BACKUP_INTERVAL_HOURS=24
|
||
CONVEX_BACKUP_RETENTION=30
|
||
# Optional Convex CLI executable and working directory overrides for the backup sidecar.
|
||
CONVEX_CLI=
|
||
CONVEX_APP_DIR=
|
||
|
||
# Development and tests ONLY: use the fake platform of @conusai-kit/testing instead of the real one.
|
||
# The app refuses this switch in a production run (anything but NODE_ENV=development or test), and
|
||
# refuses it when CONUSAI_API_URL is not on this machine or the compose network. `pnpm dev` sets it.
|
||
CONUSAI_FAKE_PLATFORM=1
|
||
# development or test. Unset means production, the safe way round.
|
||
NODE_ENV=development
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# Observability (spec §9.5). Errors need a DSN; logs and traces need the platform's OTLP endpoint.
|
||
# Without them the app runs, sends nothing, and says so in one log line at start-up.
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# The project DSN errors are sent to. Public by design (it identifies a project, it grants no read).
|
||
CONUSAI_DSN=
|
||
# Set together by the platform when the environment has OTLP instrumentation. The exporter authenticates
|
||
# with CONUSAI_API_TOKEN, so the headers variable is rarely needed.
|
||
OTEL_EXPORTER_OTLP_ENDPOINT=
|
||
OTEL_EXPORTER_OTLP_PROTOCOL=
|
||
OTEL_EXPORTER_OTLP_HEADERS=
|
||
# The service name in logs and traces. Default: app-web or app-worker.
|
||
OTEL_SERVICE_NAME=
|
||
# The release when CONUSAI_RELEASE is unset (the platform derives it from the commit).
|
||
OTEL_SERVICE_VERSION=
|
||
# debug, info, warn or error. Default info.
|
||
LOG_LEVEL=
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# Postgres: the three logins of a linked managed database (data-services DS21). web and worker never
|
||
# see the owner's URL; only the migrate job does. dev/postgres-roles.sql creates them locally.
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# The runtime role, bound by row-level security. web, worker and migrate.
|
||
POSTGRES_URL=postgresql://appdev_app:appdev_app@postgres:5432/appdev
|
||
# The global reader: the three reads that belong to no organization. web, worker and migrate.
|
||
POSTGRES_READER_URL=postgresql://appdev_reader:appdev_reader@postgres:5432/appdev
|
||
# The owner. The migrate job alone.
|
||
POSTGRES_MIGRATE_URL=postgresql://appdev_owner:appdev_owner@postgres:5432/appdev
|
||
|
||
# The mariadb and mongodb profiles instead (profiles/<name>/README.md): one login, no RLS roles,
|
||
# and the BullMQ queue on Valkey. Empty on the postgres profile; the platform injects them for a
|
||
# linked MariaDB, MongoDB (created with replica_set) and Redis/Valkey service.
|
||
# The MariaDB login. web, worker and migrate of the mariadb profile.
|
||
MARIADB_URL=
|
||
# The MongoDB replica-set URL. web, worker and migrate of the mongodb profile.
|
||
MONGODB_URL=
|
||
# The Valkey of the job queue. web and worker of the mariadb and mongodb profiles.
|
||
REDIS_URL=
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# Sign-in (spec §7). On ConusAI Cloud the project's identity link injects every OIDC_* variable and
|
||
# AUTH_PROVIDER_GENERATION; you set AUTH_SESSION_SECRET. Choose the issuer by the service you link:
|
||
# `identity` (managed Zitadel) or `better-auth` (managed Better Auth). Both feed the same oidc adapter,
|
||
# so AUTH_PROVIDER stays oidc (README.md, "Sign-in"). Locally, set the OIDC_* group yourself, or use
|
||
# AUTH_DEV_LOGIN.
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# At least 32 bytes of random secret; the key the session cookie is sealed with. Generate one with
|
||
# node -e "console.log(require('node:crypto').randomBytes(32).toString('base64url'))"
|
||
AUTH_SESSION_SECRET=replace-me-with-32-bytes-of-random-secret
|
||
# The one sign-in authority: oidc (default; the OIDC_* variables below) or convex-better-auth (the
|
||
# app-embedded Better Auth adapter: the BETTER_AUTH_* variables below; `kit template:prune --auth oidc`
|
||
# removes it from an app that does not use it). Better Auth mode refuses every OIDC_* variable and
|
||
# AUTH_DEV_LOGIN (blank both), and needs AUTH_IDENTITY_NAMESPACE instead.
|
||
AUTH_PROVIDER=
|
||
# Better Auth only: the stable namespace its users are mapped under, e.g. better-auth:notes-production.
|
||
# Never an issuer URL. Leave it empty for oidc, whose namespace is OIDC_ISSUER.
|
||
AUTH_IDENTITY_NAMESPACE=
|
||
# kit:convex-better-auth:begin
|
||
# Better Auth only: this app's Better Auth Convex deployment (better-auth/, deployed by the migrate job,
|
||
# or the convex-deploy job on the Convex profile). On ConusAI Cloud the project's `better-auth` Convex
|
||
# link injects these three (runtime-only); set them here for local development. Its URL, where the web server validates every
|
||
# request's session and the revocation relay reads the outbox, and its site URL, where Better Auth's
|
||
# routes are (the app's /api/auth forwards to them).
|
||
BETTER_AUTH_CONVEX_URL=
|
||
BETTER_AUTH_CONVEX_SITE_URL=
|
||
# Better Auth only: the deployment's admin key. Server-side only (web, the worker and the deploy job;
|
||
# on the Convex profile the deploy job also installs it, with the URL and the namespace, in the app's
|
||
# own Convex deployment, whose account actions end a deleted person's Better Auth account): it never
|
||
# validates a person, and never reaches a browser.
|
||
BETTER_AUTH_CONVEX_ADMIN_KEY=
|
||
# Better Auth only: Better Auth's own secret, at least 32 random characters. The deploy job alone
|
||
# holds it and installs it in the Better Auth deployment; the web server never sees it.
|
||
BETTER_AUTH_SECRET=
|
||
# Better Auth only: how often, in milliseconds, the web server delivers the revocation outbox (a
|
||
# sign-out elsewhere, a revoked device, a disabled or deleted account). Default 2000.
|
||
BETTER_AUTH_RELAY_INTERVAL_MS=
|
||
# kit:convex-better-auth:end
|
||
# An OIDC issuer (managed Identity, managed Better Auth -- whose issuer ends in /api/auth -- or any
|
||
# other) and this app's client. All three, or none. In development, none renders the pages signed out and
|
||
# sign-in refuses until a provider is configured. A production start with none is refused: every route
|
||
# answers 503 and /api/ready says what to set.
|
||
OIDC_ISSUER=
|
||
OIDC_WEB_CLIENT_ID=
|
||
# The API resource audience this app's API accepts in an access token. Never the client id: the boot
|
||
# refuses OIDC_AUDIENCE equal to OIDC_WEB_CLIENT_ID.
|
||
OIDC_AUDIENCE=
|
||
# Optional RFC 8707 resource URI from the selected identity link, forwarded at sign-in/exchange/refresh.
|
||
# Managed Better Auth sets it; it must equal OIDC_AUDIENCE, or the boot refuses it.
|
||
OIDC_RESOURCE=
|
||
# Only for a confidential client; the default public client uses PKCE and needs none.
|
||
OIDC_WEB_CLIENT_SECRET=
|
||
# Optional server-only resource-status credential, limited to this link's audience. Set both or neither.
|
||
OIDC_INTROSPECTION_CLIENT_ID=
|
||
OIDC_INTROSPECTION_CLIENT_SECRET=
|
||
# Optional server-only policy-bridge URL a managed provider (Better Auth) supplies with that credential.
|
||
# Without it, status uses the issuer's advertised introspection endpoint. Requires the credential.
|
||
OIDC_RESOURCE_STATUS_URL=
|
||
# Optional server-only issuer backchannel a managed provider (Better Auth) supplies: its address on this
|
||
# app's private network. The server sends its own OIDC requests there; the issuer and every browser URL
|
||
# stay OIDC_ISSUER. Needed where the app cannot reach its own public issuer (a single-host install).
|
||
OIDC_BACKCHANNEL_URL=
|
||
# Optional introspection claim an active answer must carry (managed Zitadel: the project-roles claim).
|
||
# Requires the credential.
|
||
OIDC_INTROSPECTION_REQUIRED_CLAIM=
|
||
# The managed identity link's server-only admission credential and the link's id, both injected by the
|
||
# link: an invitation then asks the platform to admit the invited address as `user` (ADR-062). Set both
|
||
# or neither; without them an invitation still works and admission is skipped (the log says why).
|
||
OIDC_ADMISSION_TOKEN=
|
||
OIDC_LINK_ID=
|
||
# Scopes asked of the provider. Default: openid profile email offline_access.
|
||
OIDC_SCOPES=
|
||
# Monotonic active-link generation. Existing links use 1; every provider cutover/rollback uses a new value.
|
||
AUTH_PROVIDER_GENERATION=
|
||
# Plain-HTTP discovery, outside production only (a local provider).
|
||
OIDC_ALLOW_INSECURE=
|
||
# 1 lets anyone in by e-mail address, with no identity provider. Refused at boot in production.
|
||
AUTH_DEV_LOGIN=1
|
||
# Whether any signed-in person may create an organization (true, the default). false: only a person
|
||
# the identity link grants the app-access role `admin` may (ADR-062 decision 5); everyone else joins by
|
||
# invitation.
|
||
APP_ORGANIZATION_SELF_SERVICE=
|
||
# true: one deployment, one organization. The first person founds it and everybody after is invited, and the
|
||
# app opens in its default workspace; an administrator may add more from the scope switcher. Default false.
|
||
APP_SINGLE_ORGANIZATION=
|
||
# 1 drops the Secure flag from the session cookie, for http://127.0.0.1. Refused at boot in production.
|
||
AUTH_INSECURE_COOKIES=1
|
||
# The session cookie's name. Default conusai_session.
|
||
AUTH_COOKIE_NAME=
|
||
# Session lifetime in seconds: idle 12 h and absolute 14 days by default.
|
||
AUTH_SESSION_IDLE_SECONDS=
|
||
AUTH_SESSION_ABSOLUTE_SECONDS=
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# This app
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# How many days a finished agent run (its step log and its conversation) is kept before the hourly sweep
|
||
# deletes it (modules/agent). A whole number from 1 to 3650; 90 when blank.
|
||
AGENT_RUN_RETENTION_DAYS=
|
||
|
||
# The model the AI gateway is asked for when a document is read (modules/documents).
|
||
AI_MODEL=
|
||
# Which search backend the knowledge module uses. "platform" is the default and the only one: the
|
||
# platform's knowledge service owns chunking, embeddings and the vector store, and the deployment token
|
||
# needs `knowledge.collections:use` (conusai.json asks for it). Any other value stops the app at start.
|
||
KNOWLEDGE_BACKEND=
|
||
# The embeddings model `platform.models.embed` asks the gateway for, for a module of yours that embeds
|
||
# text itself. Retrieval does not read it; the platform injects no default.
|
||
AI_EMBEDDING_MODEL=
|
||
# The kinds of page the documents extraction never asks the model about: a comma list of text, table,
|
||
# drawing, scan, empty. Without it, drawings and empty pages are left out and reported on the document.
|
||
# An empty value reads every page.
|
||
DOCUMENTS_EXCLUDED_PAGE_CLASSES=
|
||
# Where the worker writes the heartbeat its healthcheck reads. Default /tmp/worker-heartbeat.
|
||
WORKER_HEARTBEAT_FILE=
|
||
# kit:guides:begin
|
||
# The guides module's publish credential: a short-lived `guides:publish-code` token the platform
|
||
# hands the migrate service alone, for a deployment a member started, and revokes when the deploy
|
||
# job ends. Never set it yourself; without it the migrate job skips publishing code guides and says so.
|
||
CONUSAI_GUIDES_PUBLISH_TOKEN=
|
||
# The deployment's provenance JSON sent with it (deployment_id, source_revision, generation,
|
||
# requested_by), set by the platform beside the token.
|
||
CONUSAI_GUIDES_DEPLOYMENT=
|
||
# kit:guides:end
|
||
# kit:support:begin
|
||
# The support module's channel: the public key (spk_...) of a Support channel in this app's project,
|
||
# created in the console under Support -> Channels. It grants nothing by itself; widget sessions are
|
||
# minted with the deployment token (`support:widget-sessions`). Empty: no launcher.
|
||
CONUSAI_SUPPORT_CHANNEL=
|
||
# kit:support:end
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# `pnpm dev` and `pnpm e2e` (scripts/dev.mjs, e2e/support/stack.ts)
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# The ports they use on this machine. Defaults: web 3000, fake platform 4010, Postgres 55433; the
|
||
# end-to-end run uses 3100 and 55432 so it can run beside a development stack.
|
||
DEV_WEB_PORT=
|
||
DEV_PLATFORM_PORT=
|
||
DEV_POSTGRES_PORT=
|
||
# Optional private directory for verify-shell.mjs screenshots and bounded browser diagnostics.
|
||
# Development verification only; use disposable fixtures and protect captured evidence.
|
||
CONUSAI_BROWSER_EVIDENCE_DIR=
|
||
E2E_WEB_PORT=
|
||
E2E_POSTGRES_PORT=
|
||
# `production` builds the web shell for production for that run (e2e/support/stack.ts). Empty: development.
|
||
E2E_BUILD_MODE=
|
||
|
||
# ---------------------------------------------------------------------------------------------
|
||
# Shutdown (apps/web/server.mjs, read when it runs directly: compose.yaml does not pass them)
|
||
# ---------------------------------------------------------------------------------------------
|
||
|
||
# On SIGTERM, how long the web server waits, in milliseconds, for the requests in flight, then for the runtime's drain.
|
||
# Defaults 10000 and 8000: together they stay inside compose.yaml's stop_grace_period of 20 seconds.
|
||
SHUTDOWN_REQUESTS_MS=
|
||
SHUTDOWN_FLUSH_MS=
|
||
|
||
# Assigned by the E2E global setup from the simulated deployment’s organization; leave unset for the app.
|
||
E2E_USAGE_ORGANIZATION=
|