Control Plane configuration reference
This page lists every setting of the Control Plane (API python -m eai.main, worker python -m eai.worker, media worker python -m eai.media_worker and migrations python -m eai.migrate): the environment variable that sets it, its type, its default, the values it accepts and what it does.
This page is generated by tools/docs/gen_platform_config.py from services/control-plane/src/eai/config.py: do not edit it by hand.
215 settings in 25 groups.
How the settings are read
The settings are read once per process from the environment, with the EAI_ prefix and without case: the field database_url is the variable EAI_DATABASE_URL. A .env file of the working directory is also read; a variable of the environment wins over the file. Unknown EAI_ variables are ignored by this class (integration adapters read some of them directly, see the last section). Lists accept a comma separated text (a,b) or a JSON array (["a","b"]). Booleans accept true or false, 1 or 0, yes or no, on or off. A process reads its settings at start: restart it after a change.
Where to set them
OS packages: /etc/navin-platform/platform.env (mode 0640, root:navin-platform), read by every navin-platform-* unit; check it with navin-platform check. Kubernetes: controlPlane.config of the Helm chart for the values that are not secret (ConfigMap) and controlPlane.secrets.keys for the ones pulled from OpenBao (Helm values reference). Docker Compose: deploy/compose/.env. Local development with make start: services/control-plane/local.env, created by make docker-env.
Production rules
With EAI_ENVIRONMENT=prod the API refuses to start while one rule of eai.security.startup is broken, and prints every broken rule; with staging it starts and logs them as warnings. The rules are given in the description of each setting below ("Production:"). navin-platform check runs the same rules on a package host without starting anything.
Groups
HTTP server and hardening
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_ENVIRONMENT | string | dev | dev, test, staging, prod | Logical environment. prod refuses unsafe settings at startup (see Production rules), staging logs them, dev and test allow the development helpers. |
EAI_HOST | string | 127.0.0.1 | | Bind address of python -m eai.main. The container images and the OS packages set 0.0.0.0. |
EAI_PORT | integer | 8080 | | Listening port of the API. The PORT variable, when set, wins (PaaS convention). |
EAI_ALLOWED_HOSTS | list of strings | * | | Allowlist of the Host header. Production: must list the public host names, not *. |
EAI_TRUSTED_PROXIES | list of strings | 127.0.0.1/32,::1/128 | | Peers (CIDR) allowed to set X-Forwarded-For and X-SPIFFE-ID: the gateway and the ingress controller. Production: no catch-all range such as 0.0.0.0/0. |
EAI_CORS_ORIGINS | list of strings | empty | | Origins allowed to call the API from a browser (the portal URL). Production: must not contain *. |
EAI_DOCS_ENABLED | boolean | true | | Serves /docs, /redoc and /openapi.json. Production: must be off. |
EAI_SECURITY_HEADERS_ENABLED | boolean | true | | Adds the security headers of the API to every response. |
EAI_HSTS_ENABLED | boolean | false | | Sends Strict-Transport-Security. Production: must be on. |
EAI_HSTS_MAX_AGE_SECONDS | integer | 31536000 | | max-age of the HSTS header (one year by default). |
EAI_MAX_BODY_BYTES | integer | 10485760 | | Largest request body accepted, in bytes (10 MiB by default). |
EAI_MAX_UPLOAD_BYTES | integer | 104857600 | | Largest upload (media, documents, reconciliation imports), in bytes (100 MiB by default). |
EAI_MAX_JSON_DEPTH | integer | 64 | | Deepest nesting accepted in a JSON body; a deeper body is refused. |
EAI_DEFAULT_LOCALE | string | en | en, fr | Language of the error messages when the Accept-Language header names none of the available locales. |
EAI_REPO_ROOT | path | repository root | | Folder holding contracts, catalog and sql/postgres. The OS packages set /usr/share/navin-platform. |
EAI_PROMPT_INJECTION_DEFAULT_MODE | string | detect | off, detect, block | Prompt injection guard of a tenant that has no setting of its own; a tenant setting overrides it. |
Database
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_DATABASE_URL | string | postgresql://eai:eai@localhost:5432/eai | | PostgreSQL URL of the administrator login, used by the migrations and by the worker. Production: must use sslmode=require, verify-ca or verify-full. |
EAI_RUNTIME_DATABASE_URL | string | empty | | PostgreSQL URL of the runtime login of the API (member of eai_runtime, no DDL right). Empty: EAI_DATABASE_URL. Production: TLS required as above. |
EAI_DB_POOL_MIN | integer | 1 | | Connections kept open by the pool of each process. |
EAI_DB_POOL_MAX | integer | 10 | | Largest number of connections of the pool of each process. |
EAI_AUTO_MIGRATE | boolean | false | | Applies the pending migrations when the API starts. The Helm hook and the systemd unit run python -m eai.migrate instead. |
Authentication and directory
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_AUTH_DEV | boolean | false | | Accepts the development headers X-Dev-Tenant, X-Dev-User and X-Dev-Roles instead of a token. Production: must be off (these headers authenticate anyone). |
EAI_AUTH_SPIFFE | boolean | false | | Accepts the workload identity of the X-SPIFFE-ID header set by a trusted proxy (EAI_TRUSTED_PROXIES). |
EAI_OIDC_ISSUER | string (optional) | unset | | OpenID Connect issuer whose tokens the API accepts (Keycloak realm URL). |
EAI_OIDC_AUDIENCE | string (optional) | unset | | Audience required in the tokens. |
EAI_OIDC_JWKS_URL | string (optional) | unset | | URL of the signing keys (JWKS) of the issuer. |
EAI_OIDC_GROUP_SYNC | boolean | true | | Applies the directory group mappings (claims groups and entra_groups) at each OIDC authentication. |
EAI_OIDC_PLATFORM_ADMIN_GROUPS | list of strings | navin-platform-admins | | Directory groups that give platform_admin, matched without case. Empty: rule off. |
EAI_OIDC_TENANT_ADMIN_GROUP_PREFIX | string | navin-admins- | | A group <prefix><tenant slug> gives tenant_admin on that tenant, which is also the tenant of a token without tenant claim when the user administers only one. Empty: rule off. |
EAI_JWT_ALGORITHMS | list of strings | RS256,RS384,RS512,PS256,PS384,ES256,ES384 | | Signature algorithms accepted in the tokens. HS* and none are always refused. |
EAI_JWT_LEEWAY_SECONDS | integer | 30 | | Clock skew tolerated on exp, nbf and iat. |
Local sign in
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_LOCAL_AUTH_ENABLED | boolean | true | | Portal sign in with a login and a password (POST /v1/auth/login). Turn it off once OIDC works. |
EAI_BOOTSTRAP_ADMIN_USERNAME | string | empty | | Login of the first administrator, created at API startup when it does not exist (roles platform_admin and tenant_admin). A later start never resets it. |
EAI_BOOTSTRAP_ADMIN_PASSWORD | string | empty | | One-time password of the first administrator, to change at the first sign in. Production: 12 characters minimum, letters and digits, neither the login nor a known password; remove it once used. |
EAI_BOOTSTRAP_TENANT | string | default | | Tenant of the first administrator. |
EAI_LOCAL_SESSION_TTL_SECONDS | integer | 28800 | | Lifetime of a local session (8 hours by default). |
EAI_LOCAL_AUTH_MAX_FAILURES | integer | 5 | | Wrong passwords in a row before the account is locked. |
EAI_LOCAL_AUTH_LOCKOUT_SECONDS | integer | 900 | | Duration of the lock. |
EAI_LOCAL_PASSWORD_MIN_LENGTH | integer | 12 | | Shortest password accepted. |
EAI_LOCAL_SCRYPT_N | integer | 32768 | | scrypt cost parameter N of the password hashes. |
Secrets and keys
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_MASTER_KEY | string (optional) | unset | | Platform master key (HKDF stretched, never stored in the database). Production: EAI_MASTER_KEY or EAI_OPENBAO_URL must be set. |
EAI_OPENBAO_URL | string (optional) | unset | | OpenBao address. Production: required with EAI_OPENBAO_TOKEN (audit WORM exports are signed with Transit). |
EAI_OPENBAO_TOKEN | string (optional) | unset | | OpenBao token, or the token of an agent sidecar. |
EAI_OPENBAO_KV_MOUNT | string | secret | | Mount of the KV v2 engine (tenant secrets under <mount>/data/tenants/<tenant>/). |
EAI_OPENBAO_TRANSIT_MOUNT | string | transit | | Mount of the Transit engine. |
EAI_KMS_PROVIDER | string | none | none, openbao, pkcs11 | Key management backend of eai.crypto.kms: OpenBao Transit or a client HSM over PKCS#11. |
EAI_KMS_PKCS11_MODULE | string (optional) | unset | | Path of the client PKCS#11 library (.so). Required with pkcs11. |
EAI_KMS_PKCS11_TOKEN_LABEL | string (optional) | unset | | Label of the HSM token. Required with pkcs11. |
EAI_KMS_PKCS11_PIN_FILE | string (optional) | unset | | File holding the user PIN (mounted secret), never the PIN itself. Required with pkcs11. |
Authorization and policies
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_OPENFGA_URL | string (optional) | unset | | OpenFGA address (relationship based authorization). |
EAI_OPENFGA_STORE_ID | string (optional) | unset | | OpenFGA store, written to OpenBao by the OpenFGA bootstrap. |
EAI_OPENFGA_MODEL_ID | string (optional) | unset | | OpenFGA authorization model, written to OpenBao by the OpenFGA bootstrap. |
EAI_OPA_URL | string (optional) | unset | | OPA address. |
EAI_OPA_DELIVERY | string | push | push, bundle | push uploads the opa policies to OPA on write; bundle lets OPA poll the signed bundles of POST /v1/policies/bundles and pushes nothing. |
EAI_POLICY_BUNDLE_SIGNING_KEY_FILE | string (optional) | unset | | PEM RSA private key that signs the bundles (RS256). Required with bundle. |
EAI_POLICY_BUNDLE_KEY_ID | string | eai-policy | | keyid of .signatures.json, equal to the keys entry of OPA. |
EAI_POLICY_DEFAULT | string | allow | allow, deny | Decision when no active policy of the tenant matches; a tenant setting policy_default overrides it. Any value other than deny allows. |
Model gateway and embeddings
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_LITELLM_URL | string (optional) | unset | | LiteLLM address used by the model gateway. |
EAI_LITELLM_MASTER_KEY | string (optional) | unset | | LiteLLM master key, used when EAI_LITELLM_MASTER_KEY_REF is not set. Never logged nor returned. |
EAI_LITELLM_ADMIN_URL | string (optional) | unset | | Admin API of LiteLLM (teams, virtual keys). Unset: EAI_LITELLM_URL. |
EAI_LITELLM_MASTER_KEY_REF | string (optional) | unset | | Reference of the master key: openbao:<kv path>#<field> or env://<VARIABLE>. |
EAI_LITELLM_ADMIN_TIMEOUT_SECONDS | number | 15.0 | | Timeout of a call to the LiteLLM admin API. |
EAI_RAG_EMBEDDING_MODEL | string | local-hash-256 | | Registry model with the embeddings capability, default of a new knowledge base. Production: not local-hash-256 (hashing embedder for dev and test), for example bge-m3-vllm. |
EAI_MEMORY_EMBEDDING_MODEL | string | local-hash-256 | | Embedding model of the agent memory. Production: not local-hash-256. |
EAI_RAG_RERANK_MODEL | string | empty | | Registry model with the rerank capability used by "rerank": true. Empty: no reranking. |
EAI_EMBEDDINGS_BATCH_SIZE | integer | 64 | | Texts per gateway call during ingestion and reindexing. |
Rate limits and Redis
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_RATE_LIMIT_ENABLED | boolean | true | | Turns the rate limits of the API on. |
EAI_RATE_LIMIT_PER_MINUTE | integer | 1200 | | Requests per minute per principal, or per client IP when anonymous. |
EAI_RATE_LIMIT_GATEWAY_PER_MINUTE | integer | 600 | | Requests per minute per principal on /v1/gateway/*. |
EAI_RATE_LIMIT_AUTH_FAILURES_PER_MINUTE | integer | 20 | | Failed authentications per minute per client IP before 429. |
EAI_REDIS_URL | string (optional) | unset | | Redis that shares the rate limit counters across replicas. Production: rediss:// (TLS). |
EAI_REDIS_USERNAME | string (optional) | unset | | Redis ACL user. |
EAI_REDIS_PASSWORD_FILE | string (optional) | unset | | File holding the ACL password, never the password itself. Production: required when EAI_REDIS_URL has no credentials. |
EAI_REDIS_TLS_CA_FILE | string (optional) | unset | | CA bundle for rediss://. |
Outbound guard
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_EGRESS_PRIVATE_ALLOWLIST | list of strings | empty | | Private destinations allowed for platform callers only: exact host or host:port, *.suffix or CIDR. Keep it narrow. |
EAI_EGRESS_ALLOWED_PORTS | list of integers | 80,443,8443 | | Ports allowed for public destinations. |
EAI_EGRESS_ALLOW_HTTP | boolean | false | | Allows plain http to public destinations. Production: must be off. |
EAI_EGRESS_DNS_TIMEOUT_SECONDS | number | 3.0 | | Timeout of the DNS resolution that checks a destination. |
Observability and SLO
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_OTEL_ENABLED | boolean | false | | Exports OpenTelemetry traces (OTLP endpoint: EAI_OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT). |
EAI_METRICS_TOKEN | string (optional) | unset | | Bearer token of GET /metrics, required outside dev and test. Production: 32 characters minimum. |
EAI_WORKER_METRICS_PORT | integer | 9464 | | Metrics port of python -m eai.worker. 0: off. |
EAI_MEDIA_WORKER_METRICS_PORT | integer | 9465 | | Metrics port of python -m eai.media_worker. 0: off. |
EAI_SLO_AVAILABILITY_TARGETS | string | control_plane_api=0.995,model_gateway=0.995,tool_gateway=0.995,realtime=0.995 | | Availability target per service (service=ratio, comma separated) for GET /v1/telemetry/slo. Services: control_plane_api, model_gateway, tool_gateway, realtime. Production: an invalid value is refused. |
EAI_SLO_LATENCY_TARGETS_SECONDS | string | control_plane_api=1,model_gateway=1,tool_gateway=1,realtime=1 | | Latency target per service, in seconds, same format. |
EAI_SLO_LATENCY_OBJECTIVE | number | 0.95 | | Share of the requests that must stay under the latency target. |
EAI_SLO_RETENTION_MINUTES | integer | 1440 | | Minutes of measurement buckets kept in memory by each API replica. |
EAI_TELEMETRY_SPAN_MAX_DAYS | integer | 90 | | Ceiling of the span summaries (eai.telemetry_spans), purged by the retention job. |
Background worker
Periodic jobs of python -m eai.worker. A PostgreSQL advisory lock keeps one active replica per plane. Intervals in seconds.
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_WORKER_TICK_SECONDS | number | 5.0 | | Pause between two loops of the worker. |
EAI_WORKER_LOCK_KEY | integer | 7310442001 | | Base key of the PostgreSQL advisory lock of the leader. |
EAI_WORKER_SCHEDULER_INTERVAL_SECONDS | integer | 30 | | Interval of the scheduler job (scheduled runs). |
EAI_WORKER_OUTBOX_INTERVAL_SECONDS | integer | 10 | | Interval of the event outbox drain. |
EAI_WORKER_QUOTA_EXPIRY_INTERVAL_SECONDS | integer | 60 | | Interval of the expiry of quota reservations. |
EAI_WORKER_HEARTBEAT_INTERVAL_SECONDS | integer | 60 | | Interval of the heartbeats job, which flags the runs whose heartbeat is stale. |
EAI_WORKER_HEARTBEAT_TIMEOUT_SECONDS | integer | 1800 | | Age of the last heartbeat after which an active run is moved to timed_out (never less than the stale threshold EAI_HEARTBEAT_STALE_SECONDS). |
EAI_WORKER_APPROVAL_EXPIRY_INTERVAL_SECONDS | integer | 60 | | Interval of the expiry of approval requests. |
EAI_WORKER_RETENTION_INTERVAL_SECONDS | integer | 86400 | | Interval of the retention job (one day by default). |
EAI_WORKER_BATCH_SIZE | integer | 100 | | Rows handled per job and per loop. |
EAI_WORKER_VERIFY_CHAIN_INTERVAL_SECONDS | integer | 3600 | | Interval of the audit hash chain verification (verify_chain). |
EAI_WORKER_GAUGES_INTERVAL_SECONDS | integer | 30 | | Interval of the refresh of the metric gauges. |
EAI_WORKER_EMBEDDINGS_REINDEX_INTERVAL_SECONDS | integer | 60 | | Interval of the knowledge base reindex jobs and of the memory items of another model. |
EAI_WORKER_INBOX_PURGE_SECONDS | integer | 3600 | | Interval of the inbox_purge job. |
EAI_INBOX_RETENTION_DAYS | number | 7.0 | | Days a processed row of the consumer inbox (eai.inbox_events) is kept. |
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_WORKER_MEDIA_REQUEUE_SECONDS | integer | 60 | | Interval of the media_requeue job of python -m eai.worker. |
EAI_MEDIA_JOB_LEASE_SECONDS | integer | 900 | | A running job whose updated_at is older is requeued. |
EAI_MEDIA_JOB_MAX_ATTEMPTS | integer | 3 | | Claims of a job before media_requeue fails it. |
EAI_MEDIA_WORKER_POLL_SECONDS | number | 2.0 | | Database polling interval of a media worker without NATS. |
EAI_MEDIA_WORKER_HEARTBEAT_SECONDS | number | 60.0 | | Refresh of updated_at while a job runs. |
Realtime
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_REALTIME_WS_TOKEN_TTL_SECONDS | integer | 300 | | Lifetime of a ws_token (single use, bound to the tenant and the session) of /v1/realtime/ws/{id}. |
EAI_REALTIME_WS_MAX_MESSAGE_BYTES | integer | 1048576 | | Largest WebSocket message; larger: close 1009. |
EAI_REALTIME_WS_MAX_EVENTS_PER_SECOND | number | 50.0 | | Sustained client event rate, then close 4429. |
EAI_REALTIME_WS_BURST | integer | 100 | | Client events allowed in a burst above the sustained rate. |
EAI_REALTIME_WS_MAX_SESSION_SECONDS | integer | 3600 | | Longest connection, then close 4408. |
EAI_REALTIME_WS_IDLE_TIMEOUT_SECONDS | integer | 120 | | No client event for this long: close 4408. |
EAI_REALTIME_CONSENT_REQUIRED | boolean (optional) | unset | | Voice transcription refused without an active participant consent. Unset: required everywhere except dev and test. Production: false is refused. Recording always needs consent. |
EAI_STREAM_DLP_HOLDBACK_CHARS | integer | 128 | | Characters held back at the end of a stream so that a value cut between two chunks is still detected by the output DLP. |
Analytics export
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_WORKER_ANALYTICS_EXPORT_SECONDS | integer | 60 | | Interval of the analytics_export job to ClickHouse (when EAI_CLICKHOUSE_URL is set). |
EAI_ANALYTICS_EXPORT_BATCH | integer | 5000 | | Rows per ClickHouse insert. |
EAI_ANALYTICS_EXPORT_MAX_BATCHES | integer | 20 | | Inserts per source and per run. |
EAI_ANALYTICS_EXPORT_LAG_SECONDS | number | 5.0 | | Rows younger than this wait for the next run (commits in flight). |
SIEM forwarding and WORM audit export
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_WORKER_SIEM_FORWARD_SECONDS | integer | 30 | | Interval of the siem_forward job (audit events after a watermark per tenant). |
EAI_SIEM_FORWARD_BATCH | integer | 500 | | Audit events read per tenant and per run. |
EAI_SIEM_FORWARD_ACTIONS | string | security.*,policy.*,incident.*,approval.*,secret.*,api_key.*,audit.*,dlp.*,authz.write,authz.delete,member.*,provider.disable,model.disable,agent.kill,agent.suspend,multimodal.dlp | | Action patterns sent (prefix.* or exact name, comma separated), * for the whole audit trail. Denials and failures are always sent. |
EAI_WORKER_AUDIT_WORM_SECONDS | integer | 3600 | | Interval of the audit_worm job: one signed NDJSON and its manifest per tenant and per UTC day. |
EAI_AUDIT_WORM_RETENTION_DAYS | integer | 365 | | Retention of the WORM exports, in days. |
EAI_AUDIT_SIGNING | string | auto | auto, transit, hmac | Signature of the exports: auto uses Transit when OpenBao is configured, else HMAC; hmac is for dev and test. Production: not hmac. |
EAI_OPENBAO_AUDIT_SIGNING_KEY | string | eai-audit-export | | Transit key that signs the exports (type ed25519 or ecdsa-p256). |
EAI_AUDIT_WORM_STORAGE_PROFILE | string (optional) | unset | | Platform storage profile of the export when the tenant has no profile with purpose audit_worm. Unset: the legacy EAI_S3_* store. |
Object storage
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_STORAGE_CA_BUNDLE | string (optional) | unset | | PEM file of the certificate authority of an on-premises endpoint. Production: must be readable when set. |
EAI_STORAGE_REQUEST_TIMEOUT_SECONDS | number | 30.0 | | Timeout of a storage request. |
EAI_STORAGE_PRESIGN_MAX_SECONDS | integer | 3600 | | Longest presigned URL issued. Production: between 1 and 86400. |
EAI_STORAGE_CAPABILITY_MAX_AGE_SECONDS | integer | 86400 | | Older capability verification: refused until verified again. Production: between 60 and 604800. |
Audit Gateway and evidence
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_WORKER_AUDIT_GATEWAY_SECONDS | integer | 10 | | Interval of the audit_gateway job that drains the outbox to the SIEM webhook and to NATS JetStream. |
EAI_AUDIT_GATEWAY_BATCH | integer | 500 | | Rows sent per run. |
EAI_AUDIT_GATEWAY_MAX_ATTEMPTS | integer | 12 | | Attempts after which the row stays pending and an integrity alert is opened. |
EAI_AUDIT_GATEWAY_BACKOFF_SECONDS | number | 2.0 | | Base of the exponential backoff (base * 2^(attempts-1), capped at 900 seconds). |
EAI_AUDIT_GATEWAY_NATS_SUBJECT | string | audit.events | | NATS subject suffix: events go to eai.<tenant>.<subject>. |
EAI_AUDIT_GATEWAY_NATS_STREAM | string | EAI_AUDIT | | JetStream stream, created when missing (subjects eai.*.audit.>). |
EAI_AUDIT_GATEWAY_HTTP_URL | string (optional) | unset | | SIEM HTTP collector: one POST per event, Idempotency-Key equal to the event id. |
EAI_WORKER_AUDIT_RETENTION_SECONDS | integer | 86400 | | Interval of the audit retention job. |
EAI_AUDIT_SEAL_SIGNING_KEY | string (optional) | unset | | Ed25519 PEM key of the seals, for dev and test only. |
EAI_AUDIT_SEAL_SIGNING_KEY_REF | string (optional) | unset | | OpenBao reference of the seal key, openbao:<kv path>#<field>. Production: required. |
EAI_WORKER_AUDIT_SEAL_SECONDS | integer | 300 | | Interval of the sealing job. |
EAI_AUDIT_SEAL_MAX_EVENTS | integer | 10000 | | Largest number of events under one seal. |
EAI_WORKER_AUDIT_INTEGRITY_SECONDS | integer | 900 | | Interval of the integrity check of the seals. |
EAI_AUDIT_CLOCK_SKEW_SECONDS | integer | 300 | | Largest accepted lead of event_time over the database clock. Production: between 0 and 3600. |
EAI_AUDIT_PAYLOAD_KEK | string (optional) | unset | | Envelope key of the audit payloads: openbao-transit or a 32 byte base64 key (dev and test only). Production: openbao-transit. |
EAI_AUDIT_PAYLOAD_RETENTION_DAYS | integer | 365 | | Encrypted payloads older than this are purged unless held. |
FinOps
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_FINOPS_ALERT_THRESHOLDS | string | 50,80,100 | | Budget and quota alert thresholds, percent of the limit, comma separated, each in (0, 1000]. |
SOC and AI-SDR
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_SOC_WEBHOOK_SECRET | string | empty | | HMAC secret of the signed Falco, Tetragon and OpenSearch webhooks and of the containment receipts. Empty: those routes refuse every delivery. Production: 32 characters minimum when set. |
EAI_SOC_CORRELATION_WINDOW_SECONDS | integer | 900 | | Correlation window of the event correlator. Production: between 60 and 86400. |
EAI_WORKER_SOC_VERIFY_SECONDS | integer | 120 | | Interval of the Containment Verifier (soc_verify). |
EAI_WORKER_SOC_SCAN_SECONDS | integer | 30 | | Interval of the audit scanner (soc_scan). |
Licensing
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_LICENSE_PUBLIC_KEYS | string | empty | | Ed25519 public keys of the publisher trusted to sign licences, <kid>:<base64url key> comma separated (several for a rotation). Production: test-* kids refused. |
EAI_LICENSE_EXPIRING_SOON_DAYS | integer | 30 | | Days before valid_until when the state becomes expiring_soon. Production: between 1 and 365. |
EAI_LICENSE_WARNING_DAYS | string | 30,7,1 | | Warning thresholds of the license_check job, in days, comma separated. |
EAI_WORKER_LICENSE_CHECK_SECONDS | integer | 3600 | | Interval of the license_check job. |
Context Authority and delegations
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_CONTEXT_SIGNING_KEY | string (optional) | unset | | PEM key (Ed25519 or ECDSA P-256) of the Context Authority, for dev and test only. Never logged. |
EAI_CONTEXT_SIGNING_KEY_REF | string (optional) | unset | | OpenBao reference of the key, openbao:<kv path>#<field>. Without a key the authority refuses to sign. Production: required. |
EAI_CONTEXT_ISSUER | string | urn:eai:context-authority | | Issuer of the signed contexts. |
EAI_CONTEXT_AUDIENCES | string | eai-control-plane | | Audiences accepted by POST /v1/context/verify, comma separated. |
EAI_CONTEXT_TTL_SECONDS | integer | 900 | | Default lifetime of a signed ExecutionContext. |
EAI_CONTEXT_MAX_TTL_SECONDS | integer | 3600 | | Upper bound of a context lifetime and of the window of a retired key. |
EAI_CONTEXT_LEEWAY_SECONDS | integer | 30 | | Clock skew tolerated when a context is verified. |
EAI_CONTEXT_REQUIRED | boolean | false | | Every run needs a signed context. Production: must be on. |
EAI_DELEGATION_DEFAULT_TTL_SECONDS | integer | 28800 | | Lifetime of the implicit delegation of a run. |
EAI_DELEGATION_MAX_TTL_SECONDS | integer | 86400 | | Longest delegation. |
EAI_MANDATE_MAX_TTL_DAYS | integer | 365 | | Longest mandate, in days. |
EAI_BREAK_GLASS_MAX_SECONDS | integer | 3600 | | Longest break glass access. |
EAI_WORKLOAD_SERVICE_ID | string | eai-control-plane | | Technical identity of this workload in the run contexts. |
EAI_WORKLOAD_SPIFFE_ID | string (optional) | unset | | SPIFFE ID of this workload when SPIRE issues one. |
File security
Every file is quarantined, scanned by ClamAV (HTTPS gateway in front of clamd) and YARA-X (HTTPS worker), validated, and only then handed to Docling, OCR, media storage or transcription.
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_FILE_SCAN_MODE | string | dev | dev, enforce | enforce: both engines required, none reachable gives 503 (fail closed). dev: an engine left unconfigured is noted not_configured. Any value other than dev means enforce. Production: enforce. |
EAI_CLAMAV_URLS | string | empty | | HTTPS URLs of every ClamAV gateway, comma separated (failover across all of them). Production: every URL in https. |
EAI_CLAMAV_API_KEY | string | empty | | Bearer key of the ClamAV gateways. Production: required. |
EAI_YARAX_URLS | string | empty | | HTTPS URLs of every YARA-X worker, comma separated. Production: every URL in https. |
EAI_YARAX_API_KEY | string | empty | | Bearer key of the YARA-X workers. Production: required. |
EAI_FILE_SCAN_CA_FILE | string (optional) | unset | | PEM of the authority that signed the engine certificates. Production: readable file required. |
EAI_FILE_SCAN_TIMEOUT_SECONDS | number | 60.0 | | Timeout per scan and per engine. |
EAI_FILE_SCAN_MAX_BYTES | integer | 52428800 | | Platform ceiling of a scanned file (50 MiB); a tenant policy can only lower it. |
EAI_FILE_SCAN_ARCHIVE_MAX_MEMBER_BYTES | integer | 104857600 | | Declared size of one member of a ZIP container (clamd MaxFileSize, 100 MiB). |
EAI_FILE_SCAN_ARCHIVE_MAX_TOTAL_BYTES | integer | 419430400 | | Declared total of an archive tree (clamd MaxScanSize, 400 MiB). |
EAI_FILE_SCAN_ENDPOINT_DOWN_SECONDS | number | 30.0 | | An endpoint that failed is tried last for this long. |
EAI_WORKER_FILE_SCAN_PROBE_SECONDS | integer | 60 | | Interval of the file_scan_probe job (engine gauges and signature age). |
Telephony
Connections of the Control Plane to the telephony engines of the PBX pools (ADR-0173): Asterisk AMI and ARI, Kamailio JSONRPC and LiveKit SIP Twirp.
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_TELEPHONY_CA_FILE | string (optional) | unset | | PEM bundle of the authority that signed the engine certificates (the CA of the Navin Manager), trusted on top of the default authorities for AMI over TLS, ARI, Kamailio JSONRPC and LiveKit Twirp in https. Unset: the default authorities only. A pool with tls_verify off checks no certificate. |
EAI_TELEPHONY_EPHEMERAL_ALGORITHM | string | sha256 | | Hash of the HMAC of the ephemeral credentials of the WebRTC softphones (sha1, sha256, sha384 or sha512). It must equal the ephemeral_algorithm parameter of the kamailio service of the Navin Manager (sha256 by default), otherwise Kamailio refuses every softphone. |
Memory engines
Mem0 and Cognee instances installed and operated by the Navin Manager (ADR-0174), reached by eai.domains.memory.engines. Their addresses are rendered from the mem0 and cognee bindings; their API keys are EAI_CRED_MEMORY_MEM0_API_KEY and EAI_CRED_MEMORY_COGNEE_API_KEY of the sensitive environment file, never these settings.
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_MEMORY_MEM0_URL | string | empty | | Address of the Mem0 instance of the platform, rendered from the mem0 binding. Empty: no Mem0 engine. |
EAI_MEMORY_COGNEE_URL | string | empty | | Address of the Cognee instance of the platform, rendered from the cognee binding. Empty: no Cognee engine. |
EAI_MEMORY_COGNEE_ACCESS_CONTROL | boolean | true | | ENABLE_BACKEND_ACCESS_CONTROL of the Cognee instance, as the Navin Manager renders it. |
EAI_MEMORY_ENGINES_CA_FILE | string (optional) | unset | | PEM bundle of the authority of the engine certificates (the CA of the Navin Manager). Unset: the default authorities only. |
EAI_MEMORY_ENGINES_ALLOW_HTTP | boolean | false | | Allows plain HTTP toward an engine in staging and production; refused by default. |
EAI_MEMORY_ENGINE_TIMEOUT_SECONDS | number | 10.0 | | Timeout of a call to a memory engine, in seconds. |
MCP Runtime and MCP servers
Isolated MCP instances per tenant, project and user (ToolHive Operator), created on demand and destroyed after use by the lifecycle controller. See MCP Runtime.
| Variable | Type | Default | Allowed values | Description |
|---|
EAI_MCP_RUNTIME_ENABLED | boolean | false | | Turns the MCP Runtime on. |
EAI_MCP_RUNTIME_KUBE_URL | string | empty | | Kubernetes API address. Empty: in cluster (KUBERNETES_SERVICE_HOST and the service account token). |
EAI_MCP_RUNTIME_KUBE_TOKEN_FILE | string | /var/run/secrets/kubernetes.io/serviceaccount/token | | Token file of the service account. |
EAI_MCP_RUNTIME_KUBE_CA_FILE | string | /var/run/secrets/kubernetes.io/serviceaccount/ca.crt | | CA file of the Kubernetes API. |
EAI_MCP_RUNTIME_ISSUER | string | https://control-plane.eai-platform.svc.cluster.local/mcp-runtime | | iss of the JWT the gateway gives a ToolHive proxy. |
EAI_MCP_RUNTIME_JWKS_URL | string | empty | | JWKS read by the ToolHive proxies (GET /v1/mcp/runtime/jwks of this Control Plane). |
EAI_MCP_RUNTIME_GATEWAY_NAMESPACE | string | eai-platform | | Namespace of the Control Plane pods, allowed in by Cilium. |
EAI_MCP_RUNTIME_SERVICE_SUFFIX | string | .svc.cluster.local | | Only proxy URLs ending with this suffix (in cluster) are called. |
EAI_MCP_RUNTIME_TOKEN_TTL_SECONDS | integer | 300 | | Lifetime of the JWT given to a ToolHive proxy. |
EAI_MCP_RUNTIME_PROVISIONING_TIMEOUT_SECONDS | integer | 600 | | Longest provisioning of an instance. |
EAI_MCP_RUNTIME_QUOTA_CPU | string | 8 | | CPU of the ResourceQuota of a project namespace. |
EAI_MCP_RUNTIME_QUOTA_MEMORY | string | 16Gi | | Memory of the ResourceQuota of a project namespace. |
EAI_MCP_RUNTIME_REAPER_SECONDS | integer | 60 | | Interval of the lifecycle loop in the API pods (end of lifetime, idle sleep, states, health probes, cleanups, revocations). |
EAI_MCP_INTERNAL_HOSTS | list of strings | empty | | Internal hosts where the company hosts its own MCP servers (exact host, host:port, *.suffix or CIDR). MCP servers are internal only: every other host is refused. |
EAI_MCP_CATALOG_STORAGE_PROFILE | string | empty | | Platform storage profile of the company catalogue in SeaweedFS. Empty: the templates of catalog/mcp-runtime (dev and test only, refused in production). |
EAI_MCP_CATALOG_KEY | string | mcp-runtime/templates.yaml | | Object key of the templates file. |
EAI_MCP_CATALOG_REFRESH_SECONDS | integer | 300 | | Refresh period of the catalogue. |
EAI_MCP_RUNTIME_IMAGE_REGISTRIES | list of strings | harbor.example.internal | | Registries a template image may come from. |
EAI_MCP_RUNTIME_WAKE_TIMEOUT_SECONDS | integer | 90 | | How long a call waits for a sleeping or recreated instance. |
EAI_MCP_RUNTIME_FAILURE_LIMIT | integer | 3 | | Failures within the window before the instance waits for an explicit start. |
EAI_MCP_RUNTIME_FAILURE_WINDOW_SECONDS | integer | 900 | | Window of the failure count. |
EAI_MCP_RUNTIME_HEALTH_TIMEOUT_SECONDS | number | 3.0 | | Timeout of the health probe of a ToolHive proxy (GET /health). |
EAI_MCP_RUNTIME_OTEL_ENDPOINT | string | otel-collector.observability.svc.cluster.local:4318 | | OTLP/HTTP endpoint (TLS, host:port without scheme) of the telemetry of the proxies. |
EAI_MCP_RUNTIME_OTEL_SAMPLING_RATE | string | 1.0 | | Trace sampling rate between 0 and 1.0; every MCP request is traced by default. |
EAI_MCP_RUNTIME_OTEL_CA_FILE | string | /etc/eai/ca/ca.crt | | Internal CA file copied to each project namespace. |
Variables read outside this class
Integration adapters read a few more EAI_ variables directly (for example EAI_QDRANT_URL, EAI_NATS_URL, EAI_TEMPORAL_URL, EAI_LIVEKIT_URL, EAI_CLICKHOUSE_URL, EAI_S3_ENDPOINT, EAI_OPIK_URL, EAI_OTEL_EXPORTER_OTLP_ENDPOINT). They are described with their component in the component configuration and the platform integration pages; the ones the Helm chart sets are listed in the Helm values reference.