Environment Variables
Look up Nexia local, test, production, and Cloudflare environment ownership without copying values across runtime boundaries.
Environment Variables
This reference is for Nexia maintainers who already have authorized access to the private host environment. Core is not distributed to external developers. These host commands are not prerequisites for the public CLI and cloud sandbox; start with the quickstart.
Find the receiving runtime and capability before copying a value. For ordinary App work, use Set up App development; enable optional services only through their focused guide. The inventory below is for configuring Core and its services, not for declaring App business settings.
Find a setting
- Local runtime and PHP
- Database, files, mail, realtime
- Worktree ports and tests
- Identity, tenancy, Signature
- Search and analytics
- Agent Edge and Gateway
- Tracing and optional services
- Aliases and internal names
Three files publish different views of that contract. They are not interchangeable.
| File | Authority | How it is used |
|---|---|---|
.env.example | Local Docker Compose | task setup copies it to ignored .env; Compose injects selected values into each service |
.env.testing.example | Automated PHP tests | Test bootstrap reads it as a safety fixture; use a unique database and tenant prefix per worktree |
deploy/production/.env.example | Production owner catalog | Register each value only with the owner named by its section; no process loads this file wholesale |
The production catalog includes copies of Laravel Cloud-managed framework values
only because scripts/validate-prod-env.sh validates a file. Do not manually
register a value labeled Managed. A blank value means “supply this secret or
endpoint when its capability is enabled,” not an empty production credential.
This page is exhaustive for Nexia's supported operator contract: every assignment
in the three catalogs, every supported source-level override intentionally left
out of them, and every compatibility or container-internal name that is easy to
mistake for an operator setting. Laravel and installed packages expose additional
upstream env() hooks; those are not Nexia-supported deployment inputs unless
they appear here.
Minimal example
After Set up App development, inspect the active profile without printing credentials:
rg '^(APP_ENV|DB_DATABASE|SCOUT_DRIVER)=' .envThe first run creates .env and .env.testing, starts the core profile,
migrates and seeds the databases, and leaves AGENT_SERVICE_TOKEN blank because
the Agent profile is optional. Enable that runtime separately through Enable the Agent Gateway. For isolated analysis configuration, see How Agent requests run.
When multiple worktrees run tests, change both isolation values in each
worktree's .env.testing:
DB_DATABASE=nexia_test_agent_sse
TEST_TENANCY_DB_PREFIX=test_nexia_agent_sse_
Parameters
Scope and legend
The tables group the assignments published by the local, test, and production catalogs.
blank means the file contains the key with no value. — means that
file does not assign it. Classifications are per receiving runtime: Required
must exist for that runtime, Conditional is required only when the named
capability is enabled, Optional keeps the stated default or disables the
feature, and Managed is supplied by the platform or tracked configuration.
Framework and process runtime
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
APP_NAME | Laravel | Required | No | Nexia | Nexia | Nexia-Cloud-OS | Application display name and default mail sender name |
APP_ENV | Laravel | Managed | No | local | testing | production | Selects environment-specific safety behavior |
APP_KEY | Laravel | Required; managed in production | Yes | blank | blank | base64:CHANGE_ME | Root key for Laravel application encryption and encrypted framework payloads |
APP_DEBUG | Laravel | Managed | No | true | true | false | Controls exception detail; production must stay false |
APP_URL | Laravel | Managed | No | http://localhost | http://localhost | https://nexia.to | Canonical application URL and Agent JWT issuer |
APP_LOCALE | Laravel | Optional | No | en | ko | en | Default locale |
APP_FALLBACK_LOCALE | Laravel | Optional | No | en | en | en | Translation fallback locale |
APP_FAKER_LOCALE | Laravel | Optional | No | ko_KR | ko_KR | ko_KR | Seeder and factory locale |
APP_MAINTENANCE_DRIVER | Laravel | Optional | No | file | file | file | Maintenance-mode storage |
BCRYPT_ROUNDS | Laravel | Optional | No | 12 | 4 | 12 | Password hash work factor |
LOG_CHANNEL | Laravel | Optional | No | stack | null | stack | Default log channel |
LOG_STACK | Laravel | Optional | No | single | — | single | Channels included by the stack logger |
LOG_DEPRECATIONS_CHANNEL | Laravel | Optional | No | null | — | null | Deprecation log destination |
LOG_LEVEL | Laravel | Optional | No | debug | debug | info | Minimum Laravel log severity; Gateway uses AGENT_GATEWAY_LOG_LEVEL |
OCTANE_SERVER | Laravel | Optional | No | frankenphp | — | — | Octane server implementation |
OCTANE_WORKERS | Compose | Optional | No | 1 | — | — | Local Octane worker count |
OCTANE_MAX_REQUESTS | Compose | Optional | No | 500 | — | — | Requests handled before local worker recycling |
OCTANE_MAX_EXECUTION_TIME | Laravel | Optional | No | 600 | — | — | Maximum Octane task execution time in seconds |
Data, sessions, storage, and delivery
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
DB_CONNECTION | Laravel | Managed | No | pgsql | pgsql | managed | Database driver |
DB_HOST | Laravel | Managed | No | postgres | postgres | managed | Database host |
DB_PORT | Laravel | Managed | No | 5432 | 5432 | managed | Database port |
DB_DATABASE | Laravel | Managed | No | nexia | nexia_test | managed | Central database name |
DB_USERNAME | Laravel | Managed | No | postgres | postgres | managed | Database login name |
DB_PASSWORD | Laravel, Langfuse Compose | Required; managed by attached production DB | Yes | secret | secret | blank | Database credential; self-hosted Langfuse also derives its DSN from it |
TEST_TENANCY_DB_PREFIX | Test bootstrap | Required in tests | No | — | test_nexia_ | — | Prefix of disposable parallel tenant databases; unique per worktree |
REDIS_CLIENT | Laravel | Managed | No | phpredis | phpredis | managed | Redis client implementation |
REDIS_HOST | Laravel | Managed | No | redis | redis | managed | Redis host |
REDIS_PASSWORD | Laravel | Managed | Yes | null | null | managed | Redis credential |
REDIS_PORT | Laravel | Managed | No | 6379 | 6379 | managed | Redis port |
SESSION_DRIVER | Laravel | Managed | No | redis | array | managed | Session persistence; tests keep it in memory |
SESSION_STORE | Laravel | Required in production | No | session | — | session | Keeps sessions in the dedicated, non-tenant-prefixed Redis store |
SESSION_LIFETIME | Laravel | Optional | No | 120 | — | 120 | Idle session lifetime in minutes |
SESSION_ENCRYPT | Laravel | Optional | No | false | — | — | Encrypts serialized session payloads |
SESSION_PATH | Laravel | Optional | No | / | — | — | Session cookie path |
SESSION_DOMAIN | Laravel | Optional | No | null | — | — | Session cookie domain |
CACHE_STORE | Laravel | Managed | No | redis | file | managed | Default application cache; Agent uses explicit stores for some contracts |
QUEUE_CONNECTION | Laravel | Managed | No | redis | sync | managed | Queue backend; tests execute synchronously |
FILESYSTEM_DISK | Laravel | Optional | No | local | local | local | Framework default disk, distinct from product-storage ownership |
Product storage, realtime, mail, billing, and frontend
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
PRODUCT_STORAGE_DRIVER | Laravel | Required | No | local | — | s3 | Selects ownership-aware local or S3-compatible product disks |
AWS_ACCESS_KEY_ID | Laravel storage | Conditional | Yes | blank | — | blank | S3/R2 credential identifier |
AWS_SECRET_ACCESS_KEY | Laravel storage | Conditional | Yes | blank | — | blank | S3/R2 secret credential |
AWS_DEFAULT_REGION | Laravel storage | Conditional | No | auto | — | auto | S3-compatible region |
AWS_BUCKET | Laravel storage | Conditional | No | blank | — | nexia-cloud-os-private | Private product bucket |
AWS_PUBLIC_BUCKET | Laravel storage | Conditional | No | blank | — | nexia-cloud-os | Public product bucket |
AWS_URL | Laravel storage | Conditional | No | blank | — | https://cdn.nexia.to | Public object URL base |
AWS_ENDPOINT | Laravel storage | Conditional | No | blank | — | R2 endpoint | S3-compatible API endpoint |
AWS_USE_PATH_STYLE_ENDPOINT | Laravel storage | Optional | No | false | — | false | Selects path-style instead of virtual-host requests |
BROADCAST_CONNECTION | Laravel, local runtime-mode script | Optional local; managed in production | No | log | null | reverb | Broadcast transport; local reverb selection includes the reverb service in every runtime profile |
REVERB_APP_ID | Laravel, Reverb | Conditional local; managed in production | No | blank | — | blank | Reverb application identifier |
REVERB_APP_KEY | Laravel, Reverb, Vite, local runtime-mode script | Conditional local; managed in production | No | blank | — | blank | Reverb public application key; a nonblank local value includes the reverb service in every runtime profile |
REVERB_APP_SECRET | Laravel, Reverb | Conditional local; managed in production | Yes | blank | — | blank | Reverb signing secret |
REVERB_HOST | Laravel, Vite | Conditional local; managed in production | No | reverb | — | reverb | Reverb host |
REVERB_PORT | Laravel, Vite | Conditional local; managed in production | No | 6001 | — | 443 | Reverb port |
REVERB_SCHEME | Laravel, Vite | Conditional local; managed in production | No | http | — | https | Reverb transport scheme |
REVERB_SERVER_HOST | Laravel | Optional local override | No | commented | — | — | Backend-only Reverb host when the browser-facing host is unreachable from the app container |
REVERB_SERVER_PORT | Laravel | Optional local override | No | commented | — | — | Backend-only Reverb port; falls back to REVERB_PORT |
REVERB_SERVER_SCHEME | Laravel | Optional local override | No | commented | — | — | Backend-only Reverb scheme; falls back to REVERB_SCHEME |
SANCTUM_STATEFUL_DOMAINS | Laravel Cloud | Required | No | — | — | nexia.to,*.nexia.to | Browser origins treated as stateful Sanctum clients |
MAIL_MAILER | Laravel | Conditional | No | smtp | array | log | Outbound mail transport; production log sends nothing |
MAIL_HOST | Laravel | Conditional | No | mailpit | — | blank | SMTP host |
MAIL_PORT | Laravel | Conditional | No | 1025 | — | 587 | SMTP port |
MAIL_USERNAME | Laravel | Conditional | No | null | — | blank | SMTP login name |
MAIL_PASSWORD | Laravel | Conditional | Yes | null | — | blank | SMTP credential |
MAIL_SCHEME | Laravel | Optional | No | null | — | smtp | Explicit SMTP URL scheme |
MAIL_FROM_ADDRESS | Laravel | Conditional | No | noreply@nexia.localhost | — | noreply@nexia.to | Default sender address |
MAIL_FROM_NAME | Laravel | Conditional | No | ${APP_NAME} | — | ${APP_NAME} | Default sender name |
STRIPE_KEY | Laravel | Conditional | No | blank | — | blank | Publishable billing key |
STRIPE_SECRET | Laravel | Conditional | Yes | blank | — | blank | Stripe API secret |
VITE_PUBLIC_HOST | Vite/browser | Required locally | No | localhost | localhost | — | Browser-visible local host used by frontend endpoints |
VITE_REVERB_APP_KEY | Vite/browser, local runtime-mode script | Conditional local; managed in production | No | ${REVERB_APP_KEY} | — | ${REVERB_APP_KEY} | Browser Reverb key; a nonblank local value includes the reverb service in every runtime profile |
VITE_REVERB_HOST | Vite/browser | Conditional local; managed in production | No | ${VITE_PUBLIC_HOST} | — | ${REVERB_HOST} | Browser Reverb host |
VITE_REVERB_PORT | Vite/browser | Conditional local; managed in production | No | — | — | ${REVERB_PORT} | Browser Reverb port; local frontend config falls back to FORWARD_REVERB_PORT |
VITE_REVERB_SCHEME | Vite/browser | Conditional local; managed in production | No | ${REVERB_SCHEME} | — | ${REVERB_SCHEME} | Browser Reverb scheme |
VITE_USE_POLLING | Vite | Optional | No | true | true | — | Enables filesystem polling for mounted local source |
VITE_POLL_INTERVAL | Vite | Optional | No | 3000 | — | — | Local polling interval in milliseconds |
VITE_SHOW_UI_SANDBOX | Vite/browser | Optional | No | false | — | false | Exposes the development UI sandbox when true |
For local task dev:up:* convergence, an explicitly exported process value is
read before .env, including when it is empty; the script then applies the
key's fallback (log for BROADCAST_CONNECTION, empty for the two app keys).
Reverb is required when the resolved broadcast connection is reverb or either
resolved app key is nonblank. The literal .env alias
VITE_REVERB_APP_KEY=${REVERB_APP_KEY} resolves through REVERB_APP_KEY, so it
does not enable Reverb when that source key is blank.
Local Docker ports and testing
These values belong to Docker Compose on the developer machine and never to Laravel Cloud or a container secret store.
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
FORWARD_WEB_BIND | Compose | Optional | No | 127.0.0.1 | — | — | Host interface for the application port |
FORWARD_WEB_PORT | Compose | Optional | No | 8080 | — | — | Host application port |
FORWARD_VITE_PORT | Compose | Optional | No | 5173 | — | — | Host Vite port |
FORWARD_DB_PORT | Compose | Optional | No | 54320 | — | — | Host PostgreSQL port |
FORWARD_REDIS_PORT | Compose | Optional | No | 63790 | — | — | Host Redis port |
FORWARD_MAILPIT_PORT | Compose | Optional | No | 8025 | — | — | Host Mailpit UI port |
FORWARD_MAILPIT_SMTP_PORT | Compose | Optional | No | 1025 | — | — | Host Mailpit SMTP port |
FORWARD_REVERB_PORT | Compose | Optional | No | 6001 | — | — | Host Reverb port |
FORWARD_TYPESENSE_PORT | Compose | Optional | No | 8108 | — | — | Host Typesense port |
The test fixture also disables optional observation services so they cannot change test behavior:
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
PULSE_ENABLED | Laravel tests | Managed test fixture | No | — | false | — | Disables Pulse during tests |
TELESCOPE_ENABLED | Laravel tests | Managed test fixture | No | — | false | — | Disables Telescope during tests |
NIGHTWATCH_ENABLED | Laravel tests | Managed test fixture | No | — | false | — | Disables Nightwatch during tests |
NEXIA_TEST_PROCESSES | Test runner | Optional | No | — | commented (8) | — | Caps parallel Pest workers; defaults to the container CPU count |
Nexia identity, tenancy, files, and signatures
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
ADMIN_SEEDER_EMAIL | Laravel seeder | Conditional | No | admin@nexia.dev | — | blank | First administrator identity |
ADMIN_SEEDER_PASSWORD | Laravel seeder | Conditional | Yes | password | — | blank | First administrator password; rotate or remove after seeding |
NEXIA_ADMIN_PATH | Laravel | Optional | No | admin | admin | admin | Central administration route prefix |
NEXIA_OIDC_ID_TOKEN_LEEWAY | Laravel | Optional | No | 60 | — | 60 | Accepted OIDC clock skew in seconds |
TENANCY_DB_PREFIX | Laravel | Optional | No | nexia_ | — | nexia_ | Tenant database name prefix; changing it does not rename databases |
TENANCY_PENDING_COUNT | Laravel | Optional | No | 0 | — | 0 | Number of pre-warmed tenant databases; zero disables the pool |
TENANCY_DOMAIN_RESOLVER_CACHE | Laravel | Optional | No | false | — | true | Caches tenant domain resolution |
TENANCY_DOMAIN_RESOLVER_CACHE_TTL | Laravel | Optional | No | 3600 | — | 3600 | Domain cache lifetime in seconds |
MALWARE_SCANNER | Laravel | Required for protected intake | No | passthrough | — | clamd | Selects ClamD or an explicit local waiver |
CLAMD_HOST | Laravel | Conditional | No | clamav | — | blank | Canonical reachable ClamD host |
CLAMD_PORT | Laravel | Conditional | No | 3310 | — | 3310 | Canonical ClamD TCP port |
CLAMD_CONNECT_TIMEOUT_SECONDS | Laravel | Optional | No | 2 | — | 2 | ClamD connect timeout |
CLAMD_SCAN_TIMEOUT_SECONDS | Laravel | Optional | No | 30 | — | 30 | ClamD scan timeout |
SIGNATURE_PDF_PROCESSOR_EXPECTED_VERSION | Laravel health | Optional | No | 8.71.2 | — | — | Expected PDF processor package version |
SIGNATURE_PDF_PROCESSOR_HEALTH_REQUIRED | Laravel health | Optional | No | false | — | code default true | Makes PDF runtime health a readiness requirement |
NEXIA_SIGNATURE_DISPLAY_TIMEZONE | Laravel | Optional | No | UTC | — | UTC | Display timezone for signature evidence |
APPROVAL_SESSION_EVIDENCE_FRESHNESS_MINUTES | Laravel | Optional | No | 720 | — | 720 | Maximum age of session evidence used by Approval |
SIGNATURE_ENABLED | Laravel | Optional | No | — | — | false | Master production Signature rollout switch |
SIGNATURE_TENANT_ALLOWLIST | Laravel | Optional | No | — | — | blank | Narrows Signature to listed tenants |
SIGNATURE_LEGAL_ENTITY_ALLOWLIST | Laravel | Optional | No | — | — | blank | Narrows Signature to listed Legal Entities |
SIGNATURE_PILOT_LEGAL_ENTITY_ALLOWLIST | Laravel | Optional | No | — | — | blank | Narrows the pilot cohort further |
SIGNATURE_EXECUTION_ENGINE | Laravel | Optional | No | — | — | native | Selects the Signature execution engine |
SIGNATURE_BULK_REQUEST_ENABLED | Laravel | Optional | No | — | — | false | Enables bulk Signature requests |
SIGNATURE_BULK_REQUEST_TENANT_ALLOWLIST | Laravel | Optional | No | — | — | blank | Narrows bulk requests to tenants |
SIGNATURE_BULK_REQUEST_LEGAL_ENTITY_ALLOWLIST | Laravel | Optional | No | — | — | blank | Narrows bulk requests to Legal Entities |
DOCUMENT_BINARY_MAX_FILE_KIB | Laravel | Optional | No | 51200 | — | 51200 | Per-file upload limit |
DOCUMENT_BINARY_MAX_ACTIVE_FILES | Laravel | Optional | No | 20 | — | 20 | Maximum active files per owner |
DOCUMENT_BINARY_MAX_TOTAL_KIB | Laravel | Optional | No | 256000 | — | 256000 | Aggregate active-file limit |
DOCUMENT_BINARY_MAX_EXTRACTED_CHARACTERS | Laravel | Optional | No | 2000000 | — | 2000000 | Text extraction ceiling |
DOCUMENT_BINARY_STAGE_TTL_HOURS | Laravel | Optional | No | 48 | — | 48 | Unbound staged-file lifetime |
DOCUMENT_BINARY_QUARANTINE_RETENTION_DAYS | Laravel | Optional | No | 30 | — | 30 | Quarantined-file retention |
DOCUMENT_BINARY_DEFAULT_BOUND_RETENTION_DAYS | Laravel | Optional | No | 2555 | — | 2555 | Default bound-document retention |
DOCUMENT_BINARY_EXTRACTION_TIMEOUT_SECONDS | Laravel | Optional | No | 30 | — | 30 | External text-extraction timeout |
DOCUMENT_BINARY_PDFTOTEXT_BINARY | Laravel | Optional | No | pdftotext | — | pdftotext | Executable used for PDF text extraction |
Search, analytics, and embeddings
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
SCOUT_DRIVER | Laravel Scout | Optional | No | database | database | database | Index synchronization engine |
SCOUT_QUEUE | Laravel Scout | Optional | No | false | false | true | Queues index synchronization |
SCOUT_AFTER_COMMIT | Laravel Scout | Optional | No | true | true | true | Defers index writes until transaction commit |
TYPESENSE_HOST | Laravel Scout | Conditional | No | typesense | — | blank | Typesense host |
TYPESENSE_PORT | Laravel Scout | Conditional | No | 8108 | — | 443 | Typesense port |
TYPESENSE_PROTOCOL | Laravel Scout | Conditional | No | http | — | https | Typesense protocol |
TYPESENSE_API_KEY | Laravel Scout, local Typesense | Conditional | Yes | development admin key | — | blank | Server-only administrative key |
TYPESENSE_SCOPED_KEY_PARENT | Laravel Search | Conditional | Yes | development search-only key | — | blank | Existing search-only parent used to sign tenant-scoped keys |
KNOWLEDGE_SEARCH_SEMANTIC_ENABLED | Laravel Knowledge | Optional | No | false | false | false | Enables semantic reads for the selected immutable profile |
KNOWLEDGE_SEARCH_EMBEDDING_PROFILE | Laravel Knowledge | Optional | No | none | none | none | Provider/model/version/dimension/storage generation; no production profile exists |
RESOURCE_IMPORT_HEADER_EMBEDDING_PROVIDER | Laravel Resource Import | Optional | No | none | none | none | Enables optional header-only semantic matching |
RESOURCE_IMPORT_HEADER_EMBEDDING_BASE_URL | Laravel Resource Import | Conditional | No | local Ollama URL | — | blank | Reachable Ollama /api/embed base URL |
RESOURCE_IMPORT_HEADER_EMBEDDING_MODEL | Laravel Resource Import | Conditional | No | embeddinggemma | — | embeddinggemma | Header embedding model |
Candidate retrieval follows SCOUT_DRIVER because the examples deliberately
omit SEARCH_CANDIDATE_GATEWAY. Set that advanced override only when a staged
cutover intentionally splits indexing from candidate retrieval. See Search Configuration Profiles for the full procedure.
The production validator requires the complete Typesense connection whenever
either SCOUT_DRIVER=typesense or SEARCH_CANDIDATE_GATEWAY=typesense selects
that service.
Analytics
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
GOOGLE_ANALYTICS_ENABLED | Laravel/browser | Optional | No | false | — | true | Enables consent-gated GA4 collection |
GOOGLE_ANALYTICS_MEASUREMENT_ID | Browser | Conditional | No | G-QQR7R8D9QS | — | G-QQR7R8D9QS | Public GA4 stream identifier |
GOOGLE_ANALYTICS_COLLECT_SUBDOMAINS | Laravel/browser | Optional | No | developers | — | developers | Central subdomains allowed to collect |
GOOGLE_ANALYTICS_COLLECT_TENANT_FIXTURES | Laravel/browser | Optional | No | demo | — | demo | Fixture tenants allowed to collect |
ANALYTICS_PROPERTY_ID | Laravel admin | Conditional | No | 546439209 | — | 546439209 | GA4 property queried by server-side reporting |
ANALYTICS_CREDENTIALS_PATH | Laravel admin | Conditional local | No | private storage path | — | — | Local service-account JSON path |
ANALYTICS_CREDENTIALS_BASE64 | Laravel admin | Conditional production | Yes | blank | — | blank | Filesystem-less service-account JSON |
ANALYTICS_CACHE_STORE | Laravel admin | Optional | No | file | — | redis | Reporting cache store |
ANALYTICS_CACHE_MINUTES | Laravel admin | Optional | No | 60 | — | 60 | Fresh report cache lifetime |
ANALYTICS_STALE_CACHE_MINUTES | Laravel admin | Optional | No | 10080 | — | 10080 | Stale-on-provider-failure lifetime |
ANALYTICS_CLICK_DIMENSIONS_ENABLED | Laravel/browser | Optional | No | false | — | false | Enables click-dimension reporting |
ANALYTICS_REQUEST_TIMEOUT_MILLISECONDS | Laravel admin | Optional | No | 12000 | — | 12000 | GA4 request timeout |
Agent Edge, Gateway, and web search
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
AGENT_JWT_PRIVATE_KEY_PATH | Laravel | Conditional local | No | private PEM path | blank | — | Local delegation-signing key path |
AGENT_JWT_PUBLIC_KEY_PATH | Laravel | Conditional local | No | public PEM path | blank | — | Local delegation-verification key path |
AGENT_JWT_PRIVATE_KEY_BASE64 | Laravel Cloud | Required for production Agent | Yes | blank | — | blank | Filesystem-less private PEM content |
AGENT_JWT_PUBLIC_KEY_BASE64 | Laravel Cloud | Required for production Agent | No | blank | — | blank | Matching public PEM content |
AGENT_SERVICE_TOKEN | Laravel, Edge, Gateway | Required for Agent | Yes | blank | blank | blank | Authenticates internal callbacks and derives the ticket prefilter HMAC |
AGENT_EDGE_TOKEN | Laravel, Edge | Required for Agent | Yes | development token | blank | blank | Protects Laravel-to-Worker /agent/* requests |
NEXIA_CENTRAL_BASE_URL | Edge, Gateway | Required for Agent | No | http://app:8000 | — | Wrangler-managed | Laravel bootstrap, ticket exchange, heartbeat, and callback base URL |
AGENT_GATEWAY_URL | Laravel | Required for Agent | No | local Edge URL | test Gateway URL | Worker URL | Server-side protected Edge endpoint |
AGENT_PUBLIC_STREAM_URL | Laravel/browser | Required for production Agent | No | local browser endpoint | blank | Worker /browser/agent/stream | Exact no-redirect public ticket stream URL; DB rollout policy decides who uses it |
AGENT_GATEWAY_PORT | Compose | Optional local | No | 8100 | — | — | Host port for direct Gateway diagnostics |
AGENT_CHECKPOINT_DSN_TEMPLATE | Gateway | Required for production Agent | Yes | tenant DSN template | — | blank | Per-tenant LangGraph checkpoint and durable usage-journal DSN with {tenant_id} substitution |
AGENT_GATEWAY_LOG_LEVEL | Gateway | Optional | No | INFO | — | Wrangler-managed | Gateway log severity |
AGENT_GATEWAY_DEBUG_ERRORS | Gateway | Optional diagnostics | No | false | — | code default false; optional Wrangler override | Exposes provider/tool exception detail to SSE clients when true |
AGENT_SCREEN_SEARCH_EMBEDDING_PROVIDER | Gateway | Optional | No | none | — | Wrangler-managed | none, ollama, gemini, or zai semantic reranker |
AGENT_SCREEN_SEARCH_EMBEDDING_BASE_URL | Gateway | Optional provider override | No | blank/code default | — | code default; optional Wrangler override | Gemini and Z.ai have hosted defaults; production Ollama needs a Container-reachable URL |
AGENT_SCREEN_SEARCH_EMBEDDING_API_KEY | Gateway | Conditional hosted provider | Yes | blank | — | blank | Dedicated Gemini or Z.ai screen-search key, never a chat key |
AGENT_SEARCH_PROVIDER | Laravel | Optional | No | none | — | none | Enables the self-hosted agent_search web-search bridge |
AGENT_SEARCH_BASE_URL | Laravel | Conditional | No | http://agent-search:8000 | — | blank | Reachable agent-search service URL |
AGENT_SEARCH_TOKEN | Laravel, agent-search | Conditional | Yes | blank | — | blank | Shared internal agent-search token |
SEARXNG_SECRET | SearXNG host | Conditional | Yes | blank | — | blank | Generated secret for the optional self-hosted metasearch service |
Cloudflare does not read a production .env file. wrangler.jsonc commits
non-secret Worker values and the Container/rate-limit bindings. Register
AGENT_EDGE_TOKEN, AGENT_SERVICE_TOKEN, AGENT_CHECKPOINT_DSN_TEMPLATE, and,
when needed, AGENT_SCREEN_SEARCH_EMBEDDING_API_KEY with wrangler secret put.
services/agent-gateway-edge/src/index.ts then forwards only its explicit,
nonblank allowlist into the Python Container. Setting a dashboard variable that
is absent from that allowlist does not configure the Gateway.
Langfuse, observability, and optional services
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
LANGFUSE_ENABLED | Gateway | Optional | No | false | — | false | Enables optional masked trace export; failure remains fail-open |
LANGFUSE_HOST | Gateway | Conditional | No | internal Langfuse URL | — | blank | Langfuse API base URL used by the Gateway exporter |
LANGFUSE_PUBLIC_KEY | Gateway, bootstrap | Conditional | No | development key | — | blank | Langfuse project public key |
LANGFUSE_SECRET_KEY | Gateway, bootstrap | Conditional | Yes | development key | — | blank | Langfuse project secret key |
LANGFUSE_MASK_CONTENT | Gateway | Optional | No | true | — | true | Masks prompt and completion content before export |
LANGFUSE_PORT | Local Compose | Optional | No | 3300 | — | — | Browser-published local Langfuse UI port |
LANGFUSE_SALT | Langfuse host | Required outside local | Yes | blank/dev fallback | — | blank | Server hashing salt |
LANGFUSE_ENCRYPTION_KEY | Langfuse host | Required outside local | Yes | blank/dev fallback | — | blank | Server data-encryption key |
LANGFUSE_NEXTAUTH_SECRET | Langfuse host | Required outside local | Yes | blank/dev fallback | — | blank | Langfuse login/session secret |
LANGFUSE_REDIS_DB | Langfuse host | Optional | No | 3 | — | 3 | Redis database isolated from Laravel cache/queue data |
LANGFUSE_INIT_ORG_ID | Langfuse bootstrap | Optional | No | nexia | — | nexia | Initial organization id |
LANGFUSE_INIT_PROJECT_ID | Langfuse bootstrap | Optional | No | nexia-agent | — | nexia-agent | Initial project id |
LANGFUSE_INIT_USER_EMAIL | Langfuse bootstrap | Required outside local | No | ${ADMIN_SEEDER_EMAIL} | — | blank | Initial owner login |
LANGFUSE_INIT_USER_NAME | Langfuse bootstrap | Optional | No | Nexia Dev | — | Nexia Admin | Initial owner display name |
LANGFUSE_INIT_USER_PASSWORD | Langfuse bootstrap | Required outside local | Yes | ${ADMIN_SEEDER_PASSWORD} | — | blank | Initial owner password |
LANGFUSE_NEXTAUTH_URL | Self-hosted Langfuse | Conditional | No | — | — | blank | Browser-facing authentication callback URL |
FORWARD_LANGFUSE_PORT | Self-hosted Compose | Optional | No | — | — | 127.0.0.1:3300 | Loopback-only Langfuse UI binding |
Sentry is a separate optional Laravel error and trace export:
| Variable | Receiver | Class | Secret | Local | Test | Production | Effect |
|---|---|---|---|---|---|---|---|
SENTRY_LARAVEL_DSN | Laravel | Optional | Yes | blank | — | — | Enables Sentry error delivery when nonblank |
SENTRY_TRACES_SAMPLE_RATE | Laravel | Optional | No | 0 | — | — | Performance trace sampling rate |
LANGFUSE_ENABLED=true requires a complete host and project keypair in the
Gateway runtime. When the self-hosted bootstrap is used, its seeded project
keypair must match the Gateway exporter. The production validator requires the
host and keypair. The tenant: trace-tag prefix is Gateway-owned and has no
environment override. Product usage metering is independent of Langfuse.
Compatibility aliases and internal values
Do not add these as normal keys in a new environment.
| Names | Status | Replacement or owner |
|---|---|---|
APPROVAL_FILE_SCANNER, APPROVAL_CLAMD_HOST, APPROVAL_CLAMD_PORT, APPROVAL_CLAMD_CONNECT_TIMEOUT_SECONDS, APPROVAL_CLAMD_SCAN_TIMEOUT_SECONDS | Read-only compatibility aliases; absent from the current catalogs | MALWARE_SCANNER and CLAMD_* |
MAIL_ENCRYPTION | Compatibility assignment with local value null | MAIL_SCHEME takes precedence; do not add the older name to production |
RESOURCE_IMPORT_EMBEDDING_PROVIDER, RESOURCE_IMPORT_EMBEDDING_BASE_URL, RESOURCE_IMPORT_EMBEDDING_MODEL | One-release read fallback | RESOURCE_IMPORT_HEADER_EMBEDDING_* |
SEARCH_SEMANTIC_ENABLED, SEARCH_SEMANTIC_PROVIDER | One-release read fallback | KNOWLEDGE_SEARCH_SEMANTIC_ENABLED, KNOWLEDGE_SEARCH_EMBEDDING_PROFILE |
AGENT_OLLAMA_EMBEDDING_MODEL, AGENT_GEMINI_EMBEDDING_MODEL, AGENT_ZAI_EMBEDDING_MODEL | Removed operator knobs | Gateway code owns the provider model constants |
AGENT_GATEWAY_SSE_KEEPALIVE_SECONDS, AGENT_GATEWAY_SSE_BUFFER_MAX_BYTES, AGENT_GATEWAY_SSE_BUFFER_MAX_FRAMES, AGENT_MANIFEST_FETCH_MAX_ATTEMPTS | Removed operator knobs | Cross-runtime protocol and safety constants are code-owned |
AGENT_EDGE_LOCAL_HOST, AGENT_EDGE_LOCAL_PORT, AGENT_GATEWAY_UPSTREAM_URL | Local adapter internals fixed by Compose | Not operator registrations |
QUERY_LOG_RETENTION_DAYS, FETCH_LOG_RETENTION_DAYS, SEARXNG_BASE_URL | Search-container internals | Compose and tracked patches own them |
LANGFUSE_TENANT_TAG_PREFIX | Removed operator knob | The Gateway owns the code-defined tenant: trace-tag prefix |
PLAYWRIGHT_BROWSERS_PATH, PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD, PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH, DATA_DIR | agent-search image internals | Dockerfile owns them |
HOSTNAME, DATABASE_URL, SALT, ENCRYPTION_KEY, CLICKHOUSE_*, LANGFUSE_S3_EVENT_UPLOAD_*, REDIS_CONNECTION_STRING, TELEMETRY_ENABLED, NEXTAUTH_*, LANGFUSE_INIT_PROJECT_PUBLIC_KEY, LANGFUSE_INIT_PROJECT_SECRET_KEY, MINIO_ROOT_* | Derived or fixed Langfuse container environment; several contain secrets | Compose maps operator-owned LANGFUSE_*, database, and bootstrap values into these process names; LANGFUSE_INIT_PROJECT_ID remains an operator setting |
VITE_APP_NAME | Dead name with no current reader | Use APP_NAME; do not restore the duplicate Vite assignment |
POSTMARK_MESSAGE_STREAM_ID, TYPESENSE_MAX_TOTAL_RESULTS, SEARXNG_SEARCH_FORMATS | Inactive, comment-only, or unsupported by the selected image | Not operator registrations |
AGENT_GATEWAY_CONTAINER, AGENT_BROWSER_STREAM_RATE_LIMITER | Cloudflare bindings, not environment variables | wrangler.jsonc owns them |
PYTHONDONTWRITEBYTECODE, PYTHONUNBUFFERED, PIP_DISABLE_PIP_VERSION_CHECK, UV_LINK_MODE, UV_PROJECT_ENVIRONMENT | Gateway image constants | Dockerfile owns them |
WWWGROUP, WWWUSER, AGENT_SEARCH_REF | Local build arguments | Compose/Docker build owns them; the search ref stays security-pinned |
LANGFUSE_TEST_HOST | Integration-test-only endpoint | Not an operator registration |
NEXIA_CONTRIBUTION_MANIFEST_PATH | Generated contribution-cache path override | Code owns the normal path; not a deployment registration |
NEXIA_SIGNATURE_LIVE_FIXTURE_PASSWORD, DEMO_ADMIN_PASSWORD | Local fixture command/seeder inputs; secrets | Development-only and never production catalog values |
GOOGLE_OIDC_CLIENT_ID, GOOGLE_OIDC_CLIENT_SECRET, ENTRA_OIDC_CLIENT_ID, ENTRA_OIDC_CLIENT_SECRET, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_ISSUER | Development SSO seeder inputs; secrets where named | Production identity provider configuration is database-owned, not environment-owned |
NO_COLOR, TERM, PATH | Ambient shell/process environment | The operating system owns them |
NEXIA_APP_IMAGE, NEXIA_AGENT_GATEWAY_IMAGE | Optional self-hosted Compose image inputs | docker-compose.prod.yml only; not part of the managed production catalog |
Options
Source-supported overrides outside the official catalogs
Current source can read the following names, but Nexia deliberately omits them from the supported local and production assignment catalogs. Most are upstream framework escape hatches, diagnostics, or safety constants whose code defaults should remain aligned. Treat them as advanced overrides, not values that every deployment should copy. Promote one into an official catalog only after its runtime owner, validation rule, and production need are explicit.
| Variable | Receiver | Class | Secret | Default | Effect / reason omitted |
|---|---|---|---|---|---|
APP_PREVIOUS_KEYS | Laravel | Optional rotation | Yes | blank | Comma-separated former application keys accepted during planned key rotation |
CLAMD_EXPECTED_VERSION | Laravel health | Optional | No | 1.4 | Image/readiness contract; change only with the pinned scanner release |
MAIL_URL | Laravel mail | Optional | Yes | blank | Upstream complete SMTP DSN override |
MAIL_EHLO_DOMAIN | Laravel mail | Optional | No | host from APP_URL | Upstream SMTP EHLO domain override |
MAIL_SENDMAIL_PATH | Laravel mail | Conditional | No | /usr/sbin/sendmail -bs -i | Command used when MAIL_MAILER=sendmail |
MAIL_LOG_CHANNEL | Laravel mail | Optional | No | default log channel | Dedicated channel used when MAIL_MAILER=log |
POSTMARK_API_KEY | Laravel mail | Conditional | Yes | blank | Required when MAIL_MAILER=postmark |
RESEND_API_KEY | Laravel mail | Conditional | Yes | blank | Required when MAIL_MAILER=resend |
SEARCH_CANDIDATE_GATEWAY | Laravel Search | Optional staged cutover | No | typesense when Scout uses Typesense, otherwise database | Overrides candidate retrieval independently of indexing; leave unset for the ordinary profile |
SCOUT_PREFIX | Laravel Scout | Optional | No | blank | Prefixes external index names |
SCOUT_IDENTIFY | Laravel Scout | Optional | No | false | Enables supported engine user identification |
TYPESENSE_PATH | Laravel Scout | Optional | No | blank | URL path for hosted Typesense |
TYPESENSE_CONNECTION_TIMEOUT_SECONDS | Laravel Scout | Optional | No | 2 | Connection timeout |
TYPESENSE_HEALTHCHECK_INTERVAL_SECONDS | Laravel Scout | Optional | No | 30 | Node health-check cadence |
TYPESENSE_NUM_RETRIES | Laravel Scout | Optional | No | 3 | Client retry count |
TYPESENSE_RETRY_INTERVAL_SECONDS | Laravel Scout | Optional | No | 1 | Retry delay |
TYPESENSE_IMPORT_ACTION | Laravel Scout | Optional | No | upsert | Bulk import action |
AGENT_VISION_MODELS | Local/self-hosted Gateway only | Optional | No | blank | Image-capable local-model prefix allowlist; Cloudflare intentionally does not forward it, pending catalog-owned model capability metadata |
SIGNATURE_TEMPLATE_MAXIMUM_SIGNERS | Laravel Signature | Optional | No | 8 | Boot default for the maximum signer count |
SIGNATURE_LOCAL_FIXTURE_PROFILE | Laravel Signature | Optional local/test | No | blank | Selects an explicitly named deterministic fixture profile |
SIGNATURE_BULK_REQUEST_STUCK_AFTER_SECONDS | Laravel Signature | Optional | No | 900 | Age used for bulk readiness metadata |
SIGNATURE_BULK_REQUEST_RECOVERY_SCAN_LIMIT | Laravel Signature | Optional | No | 100 | Maximum bulk rows examined by one recovery scan |
SIGNATURE_STUCK_AFTER_SECONDS | Laravel Signature | Optional | No | 900 | Age used by the stuck-operation query |
SIGNATURE_STUCK_QUERY_LIMIT | Laravel Signature | Optional | No | 100 | Maximum stuck operations returned per query |
SIGNATURE_ARTIFACT_RETENTION_YEARS | Laravel Signature | Optional | No | 7 | Default immutable artifact/evidence retention period |
SIGNATURE_DOMPDF_EXPECTED_VERSION | Laravel health | Optional | No | 3.1.6 | Expected Dompdf runtime version |
SIGNATURE_FPDI_EXPECTED_VERSION | Laravel health | Optional | No | 2.6.8 | Expected FPDI runtime version |
SIGNATURE_TCPDF_EXPECTED_VERSION | Laravel health | Optional | No | 6.11.3 | Expected TCPDF runtime version |
Production now publishes canonical MALWARE_SCANNER=clamd and CLAMD_* names.
Supply a reachable private CLAMD_HOST. The production validator reads the
canonical names first and accepts the older aliases only during their
compatibility window.
Apply changes
Laravel reads environment values through config/*.php; Vite exposes VITE_* values to browser code, so never put secrets there. Compose interpolates service configuration, and the Gateway reads process settings at startup.
After changing Laravel configuration, clear cached configuration and restart the affected long-lived process. After changing a Cloudflare secret or Wrangler variable, deploy a new Worker/Container version; changing Laravel Cloud does not inject that value into Cloudflare. A production registration is complete only when every receiving owner has the same shared secret where the table names more than one runtime.
Laravel Cloud variables Laravel config and PHP workers
Wrangler vars/bindings Public Worker topology and Container settings
Cloudflare secrets Edge trust, checkpoint, and Gateway credentials
External service host env ClamAV, Typesense, Langfuse, SearXNG, and similar services
Errors
| Error or observable state | Cause | Resolution |
|---|---|---|
Production environment file not found: ... | The validator received a nonexistent export path | Rerun it with the actual exported file |
APP_KEY must be a generated base64 key and must not contain CHANGE_ME. | Production catalog placeholder was validated | Generate the Laravel key in the target secret store |
<KEY> is missing or contains a placeholder. | A required production value is blank or still an example value | Supply it to the owner named in this page, then rerun scripts/validate-prod-env.sh |
AGENT_EDGE_TOKEN must not use the known local development token. | Production still contains the public local example token | Generate a new token and register the same value in Laravel Cloud and Cloudflare |
<KEY> must be an absolute HTTPS URL without userinfo, query, fragment, or whitespace. | A production endpoint is unsafe or malformed | Register its canonical HTTPS origin/URL without embedded credentials or query data |
AGENT_PUBLIC_STREAM_URL must use the exact /browser/agent/stream path. | The browser stream URL points at a redirect, relay, or wrong route | Register the Worker's exact public Direct SSE endpoint |
MALWARE_SCANNER must be clamd in production. | Production selected the local passthrough waiver or another driver | Deploy reachable ClamD and use the canonical scanner settings |
<KEY> must be a deployment-reachable host name or address without a scheme, path, credentials, or whitespace. | A service host contains a URL or credential | Store only the reachable host name in the host variable |
<KEY> must be an integer between 1 and 65535. | A service port is malformed or outside the TCP range | Register the receiving service's valid port |
TYPESENSE_PROTOCOL must be one of: http https. | Typesense is selected with an unsupported scheme | Use https for hosted production or the intentional internal http endpoint |
PRODUCT_STORAGE_DRIVER must be one of: local s3. | The product disk family is unsupported or blank | Select the self-contained local profile or configure the full S3-compatible block |
AGENT_SCREEN_SEARCH_EMBEDDING_PROVIDER must be one of: none ollama gemini zai. | The Gateway reranker provider is unknown | Choose a supported provider or none |
AGENT_SCREEN_SEARCH_EMBEDDING_BASE_URL for a hosted provider must be an absolute HTTPS URL without userinfo, query, fragment, or whitespace. | A custom Gemini/Z.ai endpoint is unsafe or malformed | Remove the override to use the code default, or register a clean HTTPS base URL |
RESOURCE_IMPORT_HEADER_EMBEDDING_PROVIDER must be one of: none ollama. | Resource Import selected an unsupported embedding provider | Use reachable Ollama or keep header embeddings disabled |
KNOWLEDGE_SEARCH_SEMANTIC_ENABLED must be a boolean value. | The feature flag is not a recognized boolean | Use true or false |
KNOWLEDGE_SEARCH_EMBEDDING_PROFILE must select a production-approved profile when Knowledge semantic search is enabled. | Semantic reads are enabled with none or a blank profile | Disable semantic reads until an approved immutable profile exists |
KNOWLEDGE_SEARCH_EMBEDDING_PROFILE deterministic-local-test-vector-16-v1 is not allowed in production. | The deterministic test profile leaked into production | Return to none; it is a local/test fixture only |
LANGFUSE_ENABLED must be a boolean value. | The optional tracing switch is not a recognized boolean | Use true or false |
VITE_REVERB_APP_KEY must equal REVERB_APP_KEY. | Server and browser Reverb application keys differ | Use the same platform-managed public key |
AGENT_JWT_PRIVATE_KEY_BASE64 must be the Base64 of a PEM key. | The decoded private key is not PEM key material | Register the one-line output of base64 -i private.pem in Laravel Cloud |
Agent gateway environment variable '<KEY>' is not set. The request cannot proceed until it is populated. | Edge did not forward a required Container value, or the secret is absent | Register it in Cloudflare and confirm src/index.ts forwards the canonical name |
ticket_service_unavailable | Edge lacks NEXIA_CENTRAL_BASE_URL, AGENT_SERVICE_TOKEN, or the rate-limit binding | Restore the Worker variable, secret, and binding before retrying |
Gateway health is configured: false | NEXIA_CENTRAL_BASE_URL or AGENT_SERVICE_TOKEN is empty | Configure both in the Gateway runtime |
Screen-search health is misconfigured | A hosted provider lacks its API key | Fill the canonical screen-search key or select none; readiness validates shape, not provider reachability |
ANALYTICS_CREDENTIALS_BASE64 must contain valid Base64. | The service-account JSON encoding is damaged | Re-register the JSON as single-line Base64 |
KNOWLEDGE_SEARCH_EMBEDDING_PROFILE '<PROFILE>' is not implemented by this release. | Production selected an unsupported semantic generation | Return to none and keep semantic retrieval disabled |
| Langfuse is enabled but traces remain empty | The Gateway has an incomplete host/keypair or is not exporting traces | Configure the Gateway with the Langfuse project's host/keypair and inspect export health; product usage is independent of Langfuse |
| Candidate search uses a different engine than indexing | An operator set SEARCH_CANDIDATE_GATEWAY explicitly | Remove the override to follow Scout, or complete the deliberate split profile |
| Agent web search health succeeds but actual search returns 502 | The SearXNG pair, JSON format configuration, or secret is missing | Configure both containers in the search profile and set SEARXNG_SECRET |
| Protected uploads remain unavailable | Production CLAMD_HOST is blank or unreachable | Register the reachable private scanner hostname under canonical CLAMD_HOST |
| Tenant switching causes 419 or logout | Sessions use a tenant-prefixed cache store or a domain-wide cookie | Keep SESSION_STORE=session and leave production SESSION_DOMAIN unset |
Real usage
Local Agent injection is visible in docker-compose.yml: the same
AGENT_SERVICE_TOKEN reaches the local Edge and Gateway, while the Edge adapter
uses fixed internal URLs. Cloudflare production uses a different mechanism:
(
cd services/agent-gateway-edge
pnpm exec wrangler secret put AGENT_EDGE_TOKEN
pnpm exec wrangler secret put AGENT_SERVICE_TOKEN
pnpm exec wrangler secret put AGENT_CHECKPOINT_DSN_TEMPLATE
# Only with Gemini or Z.ai screen search:
pnpm exec wrangler secret put AGENT_SCREEN_SEARCH_EMBEDDING_API_KEY
# Only with Langfuse tracing:
pnpm exec wrangler secret put LANGFUSE_ENABLED
pnpm exec wrangler secret put LANGFUSE_HOST
pnpm exec wrangler secret put LANGFUSE_PUBLIC_KEY
pnpm exec wrangler secret put LANGFUSE_SECRET_KEY
)The screen-search embedding secret command is needed only for Gemini or Z.ai.
The four Langfuse commands are needed only when optional tracing is enabled; use
the values owned by the Langfuse project (and by the self-hosted bootstrap when
that profile is used). Store non-secret screen-search settings in
wrangler.jsonc and secrets with Wrangler.
services/agent-gateway-edge/wrangler.jsonc owns NEXIA_CENTRAL_BASE_URL, the
screen-search provider, Gateway log level, Container binding, and rate limiter.
Add the optional screen-search base URL there only when overriding the Gateway
default. services/agent-gateway-edge/src/index.ts is the final authority for
which values enter the Container.
From the Core root, save the production owners’ export to the ignored tmp/production-env-export.env, then validate it before rollout. This file contains secrets; do not substitute the local development .env or commit the export:
bash scripts/validate-prod-env.sh tmp/production-env-export.envThis check covers framework safety, Agent trust/endpoints/JWT and checkpoint settings, the three embedding capability contracts, conditional Typesense credentials, canonical ClamAV configuration, and the complete Langfuse host/keypair when enabled. It validates configuration shape; it does not prove that an external service is reachable from its receiving runtime.
Related
- Configuration Ownership — decide whether a value belongs to deployment, platform, tenant, or App state.
- Search Configuration Profiles — configure Database, Typesense, and Knowledge semantic generations safely.
- Enable the Agent Gateway — register the shared secrets and verify both Agent runtime boundaries.
- Google Analytics Operations — configure consent-gated browser collection and server-side reporting.
- Octane·FrankenPHP Runtime — understand when a changed Laravel value needs a worker restart.