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
| Variable | Default | Meaning |
|---|---|---|
RAGZ_DATABASE_URL | postgresql+asyncpg://ragz:ragz@localhost:55432/ragz | Async Postgres connection string. |
RAGZ_REDIS_URL | redis://localhost:56379/0 | Redis for Celery queues, quota counters, rate limiting. |
RAGZ_QDRANT_URL | http://localhost:56333 | Vector store for retrieval. |
RAGZ_ENVIRONMENT | dev | dev | test | staging | production. production/staging trigger the fail-closed config validator. |
Security
| Variable | Default | Meaning |
|---|---|---|
RAGZ_KEK_FILE | ./data/ragz_kek | Path 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_SECONDS | 900 (15 min) | JWT access-token lifetime. |
RAGZ_REFRESH_TOKEN_TTL_SECONDS | 1209600 (14 days) | Refresh-token lifetime. |
RAGZ_REFRESH_REUSE_GRACE_SECONDS | 10 | Grace 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_DAYS | 90 | Ceiling on API key expiry — keys are never perpetual. |
Object storage & uploads
| Variable | Default | Meaning |
|---|---|---|
RAGZ_MINIO_ENDPOINT | http://localhost:59000 | S3-compatible endpoint for uploaded documents. |
RAGZ_MINIO_ACCESS_KEY | ragz | MinIO/S3 access key. |
RAGZ_MINIO_SECRET_KEY | ragz-dev-123 | MinIO/S3 secret key. Must be changed (≥16 chars, non-default) in production. |
RAGZ_MINIO_BUCKET | ragz-documents | Bucket for document blobs. |
RAGZ_MAX_UPLOAD_MB | 100 | Hard cap on a single file upload. |
RAGZ_INTERACTIVE_UPLOAD_MB | 50 | Uploads at or below this size are routed to the fast/interactive ingestion queue instead of the batch queue. |
RAGZ_ORG_MAX_DOCUMENTS | 0 (unlimited) | Per-organization document count cap. |
RAGZ_ORG_MAX_STORAGE_BYTES | 0 (unlimited) | Per-organization storage cap, enforced at upload time. |
Embeddings, rerank & OCR
| Variable | Default | Meaning |
|---|---|---|
RAGZ_TEI_URL | http://localhost:58080 | Text-Embeddings-Inference server URL (local embeddings). |
RAGZ_EMBEDDING_BACKEND | tei | tei (real, semantic) | hash (deterministic stub — dev/test only, not semantic). |
RAGZ_EMBEDDING_DIM | 1024 | Vector dimension (matches bge-m3). Each embedding model gets its own dimension-sized Qdrant collection. |
RAGZ_RERANK_URL | http://localhost:58081 | TEI cross-encoder reranker URL (local rerank). |
RAGZ_RERANK_BACKEND | tei | tei (real) | lexical (deterministic stub — dev/test only). |
RAGZ_OCR_ENABLED | true | Kill-switch for OCR on scanned/image-only PDFs (EasyOCR). Detection itself is automatic; set false to disable entirely. |
RAGZ_OCR_MIN_CHARS_PER_PAGE | 200 | Pages with fewer extracted characters than this are treated as scanned and routed to OCR. |
LiteLLM proxy & cost accounting
| Variable | Default | Meaning |
|---|---|---|
RAGZ_LITELLM_URL | http://localhost:54000 | LiteLLM gateway URL. |
RAGZ_LITELLM_MASTER_KEY | sk-ragz-dev-master | The 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_BUDGET | 8000 | Token budget for assembled chat context (retrieved chunks + history). |
RAGZ_LITELLM_USD_PER_MILLION_TOKENS | 5.0 | USD/1M-token ceiling mirrored onto each user's LiteLLM virtual key budget. 0 disables per-user budgets (local-only installs). |
RAGZ_RERANK_USD_PER_CALL | 0.0 | Estimated $ per rerank call, for cost reporting only (Cohere bills in "search units"). 0 hides $ for this feature. |
RAGZ_WEB_SEARCH_USD_PER_CALL | 0.0 | Estimated $ per web-search call, for cost reporting only (Tavily). |
RAGZ_MODEL_CATALOG_URL | LiteLLM's model_prices_and_context_window.json on GitHub | Source for the pricing/context-window catalog sync. Empty string = air-gap mode, no network call ever — bundled snapshot only. |
Web search quotas
| Variable | Default | Meaning |
|---|---|---|
RAGZ_WEB_SEARCH_DAILY_LIMIT_PER_USER | 50 | Persistent, Redis-backed daily cap on web searches per user. 0 = unlimited. |
RAGZ_WEB_SEARCH_DAILY_LIMIT_PER_ORG | 0 (unlimited) | Optional additional per-organization daily cap, off by default. |
RAGZ_TAVILY_URL | https://api.tavily.com | Tavily API endpoint (the API key itself is a stored secret, not an env var). |
SSO / callback URLs
| Variable | Default | Meaning |
|---|---|---|
RAGZ_PUBLIC_API_BASE_URL | http://localhost:8000 | Builds the OIDC redirect_uri. Must be an exact https:// origin in production/staging. |
RAGZ_FRONTEND_BASE_URL | http://localhost:5173 | Post-login redirect target. Must be an exact https:// origin in production/staging. |
Connection pools & observability
| Variable | Default | Meaning |
|---|---|---|
RAGZ_DB_POOL_SIZE | 10 | SQLAlchemy async engine pool size. |
RAGZ_DB_MAX_OVERFLOW | 20 | Extra connections allowed beyond pool size. |
RAGZ_DB_POOL_TIMEOUT_SECONDS | 30 | Seconds to wait for a pooled connection before erroring. |
RAGZ_REDIS_MAX_CONNECTIONS | 100 | Redis client pool size. |
RAGZ_HTTPX_MAX_CONNECTIONS | 100 | Outbound HTTP client pool size (LLM/provider calls). |
RAGZ_HTTPX_MAX_KEEPALIVE | 20 | Keepalive 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:
| Variable | Meaning |
|---|---|
RAGZ_BOOTSTRAP_EMAIL | Email for the first superadmin account. Must be a valid email. |
RAGZ_BOOTSTRAP_PASSWORD | Password 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:
| Variable | Default | Meaning |
|---|---|---|
LITELLM_MASTER_KEY | sk-ragz-dev-master | LiteLLM's own admin key. Must equal RAGZ_LITELLM_MASTER_KEY. |
LITELLM_SALT_KEY | sk-ragz-dev-salt | LiteLLM'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/8See Configuration for how these bootstrap variables relate to the live-editable superadmin app-settings.