Configuration

Farna Control is configured through environment variables. In a development checkout they live in a .env file in the backend/ directory; the Docker Compose and Helm installs set the same variables through their compose files and chart values. The tables below name each variable regardless of how it is supplied.

Required

Required
Variable Description
DATABASE_URL Async database connection string
SECRET_KEY At least 32 bytes, used for JSON Web Token (JWT) signing. Known placeholder values are rejected at startup.
FERNET_KEY Fernet-compatible key for credential encryption

Database

DATABASE_URL=postgresql+asyncpg://user:password@host:5432/modulo

By default, the Docker Compose setup publishes PostgreSQL on port 5432. The development Compose file (docker-compose.local.yml) also publishes it on port 5434, so use 5434 there when a local PostgreSQL server already occupies 5432.

MODULO_DB selects the backend and defaults to postgres. The accepted values are postgres, sqlite, mariadb, and mysql; MariaDB and MySQL use the aiomysql driver. Choosing sqlite disables the PostgreSQL-specific security features (row-level security, advisory locks, and flood protection), so tenant isolation falls back to filtering in the object-relational mapping (ORM) layer. See Database Abstraction for what each backend supports.

Authentication

# Static users for local development (comma-separated, user:pass format)
MODULO_USERS=admin:admin,dev:dev

Credential encryption

# Generate your own. Do not use the example key in production.
FERNET_KEY=replace-with-your-generated-key

Generate one:

python3 -c "import base64, os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())"

The output is a 32-byte key, URL-safe base64 encoded. The command needs only the Python standard library.

Public URL and licensing

These settings tell Farna Control how it is reached and which features are unlocked:

Public URL and licensing
Variable Description
MODULO_PUBLIC_URL The externally reachable base URL of your instance. Farna Control builds absolute links from it: OpenID Connect (OIDC) callback URLs, Model Context Protocol (MCP) server URLs, and the run links in human-in-the-loop (HITL) webhook payloads. Defaults to http://localhost:8000; set it to your instance’s public host before exposing Farna Control beyond local use.
MODULO_LICENSE_KEY A Team-tier license key. It unlocks the paid feature gates, such as Single Sign-On and System for Cross-domain Identity Management (SCIM) provisioning. Leave it unset in the Community tier.
MODULO_LICENSE_PUBLIC_KEY The Ed25519 public key (64 hex characters) that verifies your license key. This is the trust anchor, and it is required in production. Set it to the public key Farna Labs issued with your license. The built-in default is the public half of the development keypair, which is trusted only in debug and cannot verify a Farna Labs-issued production license.
MODULO_LICENSE_PRIVATE_KEY The Ed25519 private key (hex) Farna Control uses to sign the license keys it issues. Leave it unset unless you issue licenses yourself; an unset value disables issuance.

A Farna Labs-issued license can only verify against the public key Farna Labs issued with it. If you set MODULO_LICENSE_KEY on an instance with debug off and leave MODULO_LICENSE_PUBLIC_KEY unset, the instance refuses to start and names the missing variable, rather than booting on the Community tier. If you install a license at runtime while only the development key is available, the request fails with 422 and "reason": "anchor_mismatch" in the response body.

MODULO_FRONTEND_URL overrides where the browser lands after login and defaults to MODULO_PUBLIC_URL; you only need it when the frontend is served from a different origin than the API. See Single Sign-On.

Connectors

Connector credentials are configured per connector instance in the Connector Hub (for example, a GitHub personal access token), not through environment variables. See Connectors for example configurations and Secrets for how credentials are handled.

CORS (Cross-Origin Resource Sharing)

CORS_ORIGINS=http://localhost:5173,https://modulo.run

Logging

MODULO_LOG_LEVEL=INFO

Log output is always structured JSON, so there is no format setting. MODULO_LOG_LEVEL sets the global level and defaults to INFO. To change one module only, set a per-module override named MODULO_LOG_LEVEL_<MODULE>, with dots replaced by underscores. For example, MODULO_LOG_LEVEL_MODULO_CONNECTORS=DEBUG raises the level for modulo.connectors alone, and takes precedence over the global value.

OpenTelemetry

Telemetry is off by default. Set MODULO_TELEMETRY_ENABLED=true to turn it on.

MODULO_TELEMETRY_ENABLED=true
# OTLP (OpenTelemetry Protocol) collector endpoint
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# Service name reported in the telemetry; defaults to "Farna Control"
MODULO_OTEL_SERVICE_NAME=modulo

When telemetry is enabled, spans always export to stdout for local debugging. The OpenTelemetry Protocol (OTLP) exporter is added only when OTEL_EXPORTER_OTLP_ENDPOINT is set, so leaving that variable unset keeps tracing on stdout without sending anything off the host. On the Team tier, an administrator can also toggle telemetry at runtime through the runtime config store, without a restart. On Community, change the environment variable and restart.

Redis

REDIS_URL=redis://localhost:6379/0

Redis is required. Farna Control uses it for event coordination, rate limiting, caching, and session state, so an empty REDIS_URL fails startup with an explicit error rather than degrading to a reduced feature set. The variable defaults to redis://localhost:6379/0, so a local Redis on the default port needs no configuration.

The default docker-compose.yml publishes Redis on port 6379. The development Compose file (docker-compose.local.yml) publishes it on port 6380.

Within Redis, Farna Control uses a WebSocket event broker for live run-event streaming and a run event ring buffer for recent event replay after a reconnect.

Feature-specific settings

The variables below configure one feature each, so they are documented in full where that feature lives. They are set in the same .env file as the settings above.

Feature-specific settings
Variable What it sets Documented in
MODULO_MAX_LOCAL_CONCURRENCY Concurrent agent subprocesses for the local runtime provider (default 2) Execution Environments, Concurrency and capacity sizing
MODULO_DOCKER_HOST (or DOCKER_HOST) The Docker engine the runner_docker provider connects to Execution Environments
MODULO_E2B_API_KEY Registers the E2B runtime provider Execution Environments
MODULO_RUNNER_MACHINE_ID Distinguishes two deployments that share one Docker engine Execution Environments
MODULO_KUBERNETES_ENABLED, MODULO_KUBERNETES_NAMESPACE, MODULO_KUBERNETES_SERVICE_ACCOUNT Register and scope the Kubernetes runtime provider Kubernetes
MODULO_SCHEMA_VALIDATOR_MODE First-boot seed for the schema validation mode: lenient (default) or strict Bring Your Own Agent
MODULO_SCIM_TOKEN The bearer token SCIM provisioning requests authenticate with SCIM Provisioning
MODULO_SSO_DEFAULT_ROLE Role granted to a user provisioned through SSO (default runner) Single Sign-On (SSO)
MODULO_SAML_IDP_METADATA_URL, MODULO_SAML_IDP_METADATA_XML Security Assertion Markup Language (SAML) identity provider (IdP) metadata for the legacy single-tenant SAML endpoints Single Sign-On (SSO)
SAQ_WORKER_CONCURRENCY, SAQ_REDIS_POOL_SIZE, SAQ_WORKER_DB_POOL_SIZE Worker throughput and the database and Redis connection pools each worker holds Concurrency and capacity sizing
TRIGGER_BACKPRESSURE_MAX_AGE_SECONDS Age at which the trigger backpressure guard refuses new fires (default 3600) Concurrency and capacity sizing
DB_CAPACITY_BYTES, DB_CAPACITY_PATH, DB_CAPACITY_HARD_STOP_PCT Database storage guard thresholds Concurrency and capacity sizing