Environment Variables

Every bootstrap setting is a RAGZ_-prefixed environment variable, read once at process start (backend/src/ragz/core/config.py). Set them in .env (local dev), your Compose file, or your orchestrator's secret/config mechanism. A handful of non-RAGZ_ variables belong to sibling containers (LiteLLM) and are listed at the end.

Defaults shown are dev defaults

Every default below is safe for local development only. In RAGZ_ENVIRONMENT=production or staging, Ragz fails closed at startup if api_key_pepper is unset or short, database_url/minio_secret_key/litellm_master_key are still the dev defaults or too short, kek_file doesn't resolve to a valid key, or public_api_base_url/frontend_base_url aren't exact https:// origins.

Core services

VariableDefaultMeaning
RAGZ_DATABASE_URLpostgresql+asyncpg://ragz:ragz@localhost:55432/ragzAsync Postgres connection string.
RAGZ_REDIS_URLredis://localhost:56379/0Redis for Celery queues, quota counters, rate limiting.
RAGZ_QDRANT_URLhttp://localhost:56333Vector store for retrieval.
RAGZ_ENVIRONMENTdevdev | test | staging | production. production/staging trigger the fail-closed config validator.

Security

VariableDefaultMeaning
RAGZ_KEK_FILE./data/ragz_kekPath to the encryption root key (KEK) file. AES-256-GCM envelope-encrypts every stored secret. Auto-created on first run; back it up — losing it makes every stored secret unrecoverable.
RAGZ_API_KEY_PEPPER"" (empty)HMAC key for hashing refresh tokens and invitation tokens. Empty = plain SHA-256 (dev-compatible). Required, and required ≥16 chars, in production/staging. Rotating it logs out all sessions.
RAGZ_ACCESS_TOKEN_TTL_SECONDS900 (15 min)JWT access-token lifetime.
RAGZ_REFRESH_TOKEN_TTL_SECONDS1209600 (14 days)Refresh-token lifetime.
RAGZ_REFRESH_REUSE_GRACE_SECONDS10Grace window where a raced, already-rotated refresh token still succeeds instead of revoking the session family. 0 disables the grace window.
RAGZ_TRUSTED_PROXIES[] (empty)Comma-separated IPs/CIDRs of your own reverse proxy/CDN. Empty = trust no X-Forwarded-For header at all (direct-peer IP only). Only set this in production, behind a real proxy.
RAGZ_API_KEY_MAX_LIFETIME_DAYS90Ceiling on API key expiry — keys are never perpetual.

Object storage & uploads

VariableDefaultMeaning
RAGZ_MINIO_ENDPOINThttp://localhost:59000S3-compatible endpoint for uploaded documents.
RAGZ_MINIO_ACCESS_KEYragzMinIO/S3 access key.
RAGZ_MINIO_SECRET_KEYragz-dev-123MinIO/S3 secret key. Must be changed (≥16 chars, non-default) in production.
RAGZ_MINIO_BUCKETragz-documentsBucket for document blobs.
RAGZ_MAX_UPLOAD_MB100Hard cap on a single file upload.
RAGZ_INTERACTIVE_UPLOAD_MB50Uploads at or below this size are routed to the fast/interactive ingestion queue instead of the batch queue.
RAGZ_ORG_MAX_DOCUMENTS0 (unlimited)Per-organization document count cap.
RAGZ_ORG_MAX_STORAGE_BYTES0 (unlimited)Per-organization storage cap, enforced at upload time.

Embeddings, rerank & OCR

VariableDefaultMeaning
RAGZ_TEI_URLhttp://localhost:58080Text-Embeddings-Inference server URL (local embeddings).
RAGZ_EMBEDDING_BACKENDteitei (real, semantic) | hash (deterministic stub — dev/test only, not semantic).
RAGZ_EMBEDDING_DIM1024Vector dimension (matches bge-m3). Each embedding model gets its own dimension-sized Qdrant collection.
RAGZ_RERANK_URLhttp://localhost:58081TEI cross-encoder reranker URL (local rerank).
RAGZ_RERANK_BACKENDteitei (real) | lexical (deterministic stub — dev/test only).
RAGZ_OCR_ENABLEDtrueKill-switch for OCR on scanned/image-only PDFs (EasyOCR). Detection itself is automatic; set false to disable entirely.
RAGZ_OCR_MIN_CHARS_PER_PAGE200Pages with fewer extracted characters than this are treated as scanned and routed to OCR.

LiteLLM proxy & cost accounting

VariableDefaultMeaning
RAGZ_LITELLM_URLhttp://localhost:54000LiteLLM gateway URL.
RAGZ_LITELLM_MASTER_KEYsk-ragz-dev-masterThe proxy's own admin credential (must match the LiteLLM container's LITELLM_MASTER_KEY) — not an LLM provider key. Must be changed in production.
RAGZ_CHAT_CONTEXT_TOKEN_BUDGET8000Token budget for assembled chat context (retrieved chunks + history).
RAGZ_LITELLM_USD_PER_MILLION_TOKENS5.0USD/1M-token ceiling mirrored onto each user's LiteLLM virtual key budget. 0 disables per-user budgets (local-only installs).
RAGZ_RERANK_USD_PER_CALL0.0Estimated $ per rerank call, for cost reporting only (Cohere bills in "search units"). 0 hides $ for this feature.
RAGZ_WEB_SEARCH_USD_PER_CALL0.0Estimated $ per web-search call, for cost reporting only (Tavily).
RAGZ_MODEL_CATALOG_URLLiteLLM's model_prices_and_context_window.json on GitHubSource for the pricing/context-window catalog sync. Empty string = air-gap mode, no network call ever — bundled snapshot only.

Web search quotas

VariableDefaultMeaning
RAGZ_WEB_SEARCH_DAILY_LIMIT_PER_USER50Persistent, Redis-backed daily cap on web searches per user. 0 = unlimited.
RAGZ_WEB_SEARCH_DAILY_LIMIT_PER_ORG0 (unlimited)Optional additional per-organization daily cap, off by default.
RAGZ_TAVILY_URLhttps://api.tavily.comTavily API endpoint (the API key itself is a stored secret, not an env var).

SSO / callback URLs

VariableDefaultMeaning
RAGZ_PUBLIC_API_BASE_URLhttp://localhost:8000Builds the OIDC redirect_uri. Must be an exact https:// origin in production/staging.
RAGZ_FRONTEND_BASE_URLhttp://localhost:5173Post-login redirect target. Must be an exact https:// origin in production/staging.

Connection pools & observability

VariableDefaultMeaning
RAGZ_DB_POOL_SIZE10SQLAlchemy async engine pool size.
RAGZ_DB_MAX_OVERFLOW20Extra connections allowed beyond pool size.
RAGZ_DB_POOL_TIMEOUT_SECONDS30Seconds to wait for a pooled connection before erroring.
RAGZ_REDIS_MAX_CONNECTIONS100Redis client pool size.
RAGZ_HTTPX_MAX_CONNECTIONS100Outbound HTTP client pool size (LLM/provider calls).
RAGZ_HTTPX_MAX_KEEPALIVE20Keepalive connections held in the outbound HTTP pool.
RAGZ_SENTRY_DSN"" (off)Optional Sentry error reporting. Requires uv sync --group observability; zero dependency cost when unset.

One-time bootstrap (script, not the running app)

These are read directly by python -m ragz.bootstrap, not by the API/worker processes, and only matter on first run:

VariableMeaning
RAGZ_BOOTSTRAP_EMAILEmail for the first superadmin account. Must be a valid email.
RAGZ_BOOTSTRAP_PASSWORDPassword for the first superadmin account. Must be ≥12 characters.

Sibling containers (not RAGZ_-prefixed)

Set in .env alongside the RAGZ_* vars — these configure the LiteLLM proxy container itself, not the Ragz app:

VariableDefaultMeaning
LITELLM_MASTER_KEYsk-ragz-dev-masterLiteLLM's own admin key. Must equal RAGZ_LITELLM_MASTER_KEY.
LITELLM_SALT_KEYsk-ragz-dev-saltLiteLLM's at-rest encryption salt.
# .env — minimal production-safe overrides
RAGZ_ENVIRONMENT=production
RAGZ_DATABASE_URL=postgresql+asyncpg://ragz:CHANGE_ME_LONG_RANDOM@db-host:5432/ragz
RAGZ_KEK_FILE=/secure/ragz_kek
RAGZ_API_KEY_PEPPER=$(openssl rand -hex 32)
RAGZ_MINIO_SECRET_KEY=CHANGE_ME_LONG_RANDOM
LITELLM_MASTER_KEY=sk-CHANGE_ME
LITELLM_SALT_KEY=sk-CHANGE_ME
RAGZ_LITELLM_MASTER_KEY=sk-CHANGE_ME
RAGZ_PUBLIC_API_BASE_URL=https://ragz.example.com
RAGZ_FRONTEND_BASE_URL=https://ragz.example.com
RAGZ_TRUSTED_PROXIES=10.0.0.0/8

See Configuration for how these bootstrap variables relate to the live-editable superadmin app-settings.