Skip to content

Configuration reference ​

What this page covers: every setting you are likely to change when you install and run mmune, grouped by area. You set them as environment variables for the backend, in the .env file that sits next to the Compose file in your delivered package. This page tells you what each variable does, whether you must set it, and what happens when you leave it alone. It also lists the smallest set of values you need for a first start.

Related pages: Account and access explains the accounts, roles and license states that several of these settings control, and the API overview describes the HTTP interface.

How values are loaded ​

The backend reads its settings from environment variables when it starts. In a packaged install, Docker Compose takes the values from the .env file next to the Compose file and passes them into the containers. A container install is configured by environment variables alone, so there are no additional configuration files to edit. After you change a value, recreate the containers so the backend picks it up.

Leave an optional variable unset instead of writing KEY= with nothing after the equals sign. Compose passes a blank value on as an empty string, and several settings are parsed as numbers, so an empty string stops them from working. The example .env file in your package keeps optional keys commented out for this reason.

Most true or false settings accept 1, true, yes and on, in any letter case. A few accept only 1, true and yes, including MMUNE_AUTO_DUPLICATE_SCAN, MMUNE_HANA_SSL_VALIDATE and the three *_ROW_COUNT_EXACT settings. Use true and false when in doubt.

In the tables below, "Required" means the Compose file refuses to start, or the backend refuses to boot in prod mode, when the value is missing. Values in angle brackets, such as <GENERATE-A-STRONG-VALUE>, are placeholders you must replace.

Minimum settings for a first start ​

A production install needs these values before it will start.

SettingWhat to put there
POSTGRES_PASSWORD, REDIS_PASSWORD, RABBITMQ_PASSWORD, GRAFANA_PASSWORDA separate strong password for each service.
JWT_SECRET_KEY and APP_SECRET_KEYTwo different random values. See Generating strong values.
ENCRYPTION_KEYA random key that protects stored credentials. Back it up.
MMUNE_ADMIN_PASSWORD and MMUNE_USER_PASSWORDStrong passwords for the two initial accounts.
MMUNE_SCAN_TARGETSThe networks or hosts mmune should scan. The backend starts without it, but nothing is discovered.
A licenseDeliver the license file with or before the first start. Without one, monitoring and AutoPilot do not run. See Licensing.

An AI provider key is optional. Without one, mmune uses its built-in pattern engine and still works.

Generating strong values ​

Generate each secret on a trusted machine and store it in your own secret store as well as the .env file.

bash
# 64 hex characters, suitable for JWT_SECRET_KEY, APP_SECRET_KEY and ENCRYPTION_KEY
openssl rand -hex 32

# a random password or probe key
openssl rand -base64 24

Use a different value for every variable. Never reuse a password from another system.

Runtime mode ​

VariableRequiredDefaultWhat it does
MMUNE_MODEOptionalprod in the packaged Compose fileSet to prod. The backend runs only against your real systems and refuses to start with missing secrets.
MMUNE_LOG_RENDEREROptionaljsonSet to console for human-readable logs. Any other value gives JSON logs.

Authentication and security ​

VariableRequiredDefaultWhat it does
JWT_SECRET_KEYRequirednoneSource of the session signing secret. Compose passes it to the backend as MMUNE_JWT_SECRET.
MMUNE_JWT_SECRETRequired in prodtaken from JWT_SECRET_KEYSecret that signs sign-in tokens. In prod the backend refuses to issue or accept tokens without it.
MMUNE_JWT_SECRET_PREVIOUSOptionalunsetThe old signing secret, accepted for verification only while you rotate to a new one. New tokens always use MMUNE_JWT_SECRET. Remove it once old sessions have expired.
APP_SECRET_KEYRequirednoneApplication secret that the Compose file requires you to set.
ENCRYPTION_KEYRequirednoneKey for the encrypted credential store. In prod the backend refuses to start without it. If you lose it, every stored credential becomes unreadable, so back it up. A 64-character hex value is accepted.
MMUNE_ADMIN_PASSWORDRequired in prodnonePassword of the initial administrator account. In prod the account is not created without it. Choose a strong, unique value.
MMUNE_USER_PASSWORDRequired in prodnonePassword of the initial read-only account. Choose a strong, unique value.
MMUNE_READ_ONLYOptionaltrueBlocks real script execution and hides agent tools that change things. Only an explicit false, 0 or no allows them.
MMUNE_PROBE_KEYOptionalunsetShared secret that probes present when they send heartbeats, in the X-Probe-Key header. While it is unset the heartbeat endpoint answers 503, so probe enrollment is closed.
CORS_ORIGINSOptionallocal development addresses onlyComma-separated list of browser origins allowed to call the API. Add the address users open the console at if it differs from MMUNE_API_URL.
MMUNE_RATE_LIMIT_GLOBAL_CALLSOptional6000Requests allowed per window across all callers.
MMUNE_RATE_LIMIT_GLOBAL_PERIODOptional60Length of the global window in seconds.
MMUNE_RATE_LIMIT_PER_KEY_CALLSOptional18000Requests allowed per window for one caller.
MMUNE_RATE_LIMIT_PER_KEY_PERIODOptional3600Length of the per-caller window in seconds.

In prod mode the backend also needs a reachable Redis, which it uses for rate limiting and for revoking tokens across replicas. It refuses to start without it.

Public URL and network binding ​

VariableRequiredDefaultWhat it does
MMUNE_API_URLOptionalhttp://localhost:8000 in the packaged Compose filePublic URL of the backend. The backend adds its origin to the allowed CORS origins. Standalone probe agents need it and exit when it is unset.
MMUNE_HTTP_BINDOptional127.0.0.1Address the console's plain HTTP port 80 listens on. By default the only external listener is HTTPS on port 443. Setting 0.0.0.0 also serves the console over plain HTTP, which is suitable for a lab only.
MMUNE_TLS_CNOptionalmmune.localCommon name and subject alternative name of the self-signed certificate created on first boot. For production, mount a certificate issued by your own certificate authority instead.
MMUNE_FRONTEND_BASE_URLOptionalunsetBase address of the console, used to build links back to mmune inside tickets.

Database, cache and message broker ​

The packaged Compose file runs PostgreSQL, Redis and RabbitMQ for you and builds the connection strings from the values below.

VariableRequiredDefaultWhat it does
POSTGRES_PASSWORDRequirednonePassword of the PostgreSQL service.
POSTGRES_USEROptionaladminPostgreSQL user created by the Compose file.
POSTGRES_DBOptionalmmune_kbDatabase name.
MMUNE_DATABASE_URLOptionalbuilt by Compose from the PostgreSQL valuesConnection URL of the metadata database. Set it only to use an external PostgreSQL server, for example postgresql://<user>:<password>@db.example.local:5432/mmune_kb.
MMUNE_DB_POOL_SIZEOptional5Database connection pool size. Raise it for large estates, because each concurrent monitoring check needs a connection.
MMUNE_DB_POOL_MAX_OVERFLOWOptional10Extra connections allowed beyond the pool size.
REDIS_PASSWORDRequirednonePassword of the Redis service. Compose builds the Redis URL from it.
REDIS_URLOptionalbuilt by ComposeConnection URL of Redis. Set it to use an external Redis.
RABBITMQ_PASSWORDRequirednonePassword of the RabbitMQ service.
RABBITMQ_USEROptionalmmuneRabbitMQ user created by the Compose file.
RABBITMQ_VHOSTOptionalmmuneRabbitMQ virtual host.
GRAFANA_PASSWORDRequirednoneAdmin password of the bundled Grafana dashboards.

AutoPilot and discovery ​

AutoPilot onboards integrations without per-integration action from you. After you set the values below once, a backend restart drives discovery, registration and introspection, then lineage, semantic mappings and monitoring.

VariableRequiredDefaultWhat it does
MMUNE_AUTOPILOT_ENABLEDOptionaltrue in the packaged Compose fileStarts the AutoPilot loop when the backend starts.
MMUNE_SCAN_TARGETSRequired for anything to onboardemptyComma-separated networks in CIDR form or host names to scan, for example 10.0.0.0/24,db01.example.local.
MMUNE_SCAN_PORTSOptionalbuilt-in list of common database and service portsReplaces the built-in port list when set, for example 5432,1521.
MMUNE_SCAN_PORT_RANGEOptionalunsetExtra port ranges to sweep in addition to the known ports, for example 1-1024,8000-9000. A range wider than about 5000 ports is skipped entirely rather than shortened.
MMUNE_EXTRA_DB_PORTSOptionalunsetExtra port:provider hints for identifying services on non-standard ports, for example 1521:oracle,50000:db2.
MMUNE_AUTOPILOT_INTERVALOptional120Seconds between reconcile cycles. Values below 30 are raised to 30.
MMUNE_RESCAN_INTERVALOptional3600Seconds between full network re-scans for new systems. 0 turns periodic re-scans off.
MMUNE_CREDENTIAL_FILEOptionalclient-credentials.yamlFile name of your credential profile file. It sits next to the Compose file and is mounted read-only into the backend.
MMUNE_CREDENTIAL_PROFILESOptionalthe mounted credential filePath inside the container of the credential profile file. mmune uses a matching profile from your credential file; if none matches, the integration is marked as needing credentials.
MMUNE_REGISTER_DETECTED_ONLYOptionalfalseBy default, infrastructure endpoints that mmune detects are listed but not registered, so they use no license seat. Set to true to configure, test and register them too.
MMUNE_WATCHDOG_MAX_CONCURRENTOptional10Most integration checks that run at the same time in one monitoring cycle. It limits parallelism, not how many integrations you can have.
MMUNE_ESTATE_LOAD_CEILING_PER_CYCLEOptionalunlimitedMost sampling queries mmune sends to your monitored systems per cycle. Plain reachability checks are never limited by it.
MMUNE_AUTO_DUPLICATE_SCANOptionalfalseSamples a small set of rows from the most identity-like table of each newly discovered PostgreSQL or MySQL system and runs duplicate detection on it.
MMUNE_AUTO_DUPLICATE_SCAN_ROWSOptional200Rows sampled per automatic duplicate scan. The hard limit is 1000.

Licensing ​

mmune checks its license offline against a signed token, so it never contacts the vendor. A license in the valid or grace state allows monitoring. Without a valid license the backend still starts, but monitoring and AutoPilot stay off until a license is applied. An administrator can apply a renewal without restarting. The states and the renewal steps are described in Account and access.

VariableRequiredDefaultWhat it does
MMUNE_LICENSE_FILEOptional/var/lib/mmune/license/mmune.licensePath of the license file inside the container. The path is on a persistent volume.
MMUNE_LICENSEOptionalunsetThe license token itself, as an alternative to the file. mmune checks a license stored by an earlier renewal first, then the file, then this variable.

AI providers and local models ​

mmune works without any AI key, using a built-in pattern engine. A key adds chat, semantic enrichment and orchestration. Set one or more providers and choose the default.

VariableRequiredDefaultWhat it does
DEFAULT_AI_PROVIDEROptionalgemini in the packaged Compose fileOne of gemini, openai, claude or ollama. The aliases google_gemini, anthropic, anthropic_claude and local are also accepted. The air-gapped package pins it to ollama.
GEMINI_API_KEYOptionalunsetGoogle Gemini key. GOOGLE_API_KEY is also accepted. GEMINI_DEFAULT_MODEL overrides the model.
OPENAI_API_KEYOptionalunsetOpenAI key. OPENAI_DEFAULT_MODEL overrides the model, and OPENAI_API_BASE points mmune at an OpenAI-compatible gateway.
ANTHROPIC_API_KEYOptionalunsetAnthropic key. ANTHROPIC_DEFAULT_MODEL overrides the model.
MMUNE_LOCAL_LLM_BASE_URLOptionalunsetBase URL of any OpenAI-compatible local model server, for example http://ollama:11434/v1.
MMUNE_LOCAL_LLM_MODELRequired with the base URLunsetChat model name on the local server. Without it the local provider is not registered and a warning is logged. The air-gapped package defaults it to qwen3:0.6b.
MMUNE_LOCAL_LLM_EMBED_MODELOptionalunsetEmbedding model name, for local servers that serve embeddings.
MMUNE_LOCAL_LLM_API_KEYOptionallocalKey sent to the local server. Most local servers ignore it.
MMUNE_LOCAL_LLM_TIMEOUT_SECONDSOptional120Per-request timeout for the local model. If you raise it, also raise the read timeout of the web proxy in front of mmune (660 seconds by default), or a slow model can still produce a 504 error.
MMUNE_LOCAL_LLM_MAX_INFLIGHTOptional2Most local requests that run at once. Extra requests wait their turn.
MMUNE_LOCAL_LLM_NUM_CTXOptional4096Context size used to trim prompts before they reach the local model.
MMUNE_LLM_TIMEOUT_SECONDSOptional30Per-attempt timeout for cloud providers. mmune retries failed calls.
MMUNE_LLM_ENRICHMENT_ENABLEDOptionalfalseAdds AI enrichment on top of rule-based advisor findings. Findings marked as AI-generated need this on.
MMUNE_AI_BUDGET_DAILY_USDOptionalunlimitedDaily ceiling on AI spend across mmune. Per-integration budgets saved in mmune take precedence.
MMUNE_AI_BUDGET_MONTHLY_USDOptionalunlimitedMonthly ceiling on AI spend.
MMUNE_AI_COMPONENT_ROUTINGOptionalunsetJSON map from a component name to an ordered list of providers, for example {"chat": ["ollama"]}. Invalid JSON is ignored and a warning is logged.
MMUNE_AI_LOCAL_ONLY_COMPONENTSOptionalunsetComma-separated components that may only use the local model, for example chat,advisor. Use it to keep specific data off cloud providers.

To run a model on the same host, set DEFAULT_AI_PROVIDER=ollama together with the MMUNE_LOCAL_LLM_* values and start the stack with the local-llm Compose profile enabled. On a host with a GPU, use the GPU override file delivered with your package as well.

Monitoring and drift tuning ​

The monitoring samplers read these values at startup. Each sampler can be switched off with its *_ENABLED variable, which accepts 0, false or no. The defaults suit most estates.

Structure and value drift ​

VariableRequiredDefaultWhat it does
MMUNE_REINTROSPECT_INTERVAL_SECONDSOptional300How often each integration is read again to refresh lineage and detect structural drift.
MMUNE_VALUE_SAMPLE_ENABLEDOptionaltrueTurns the value and semantic drift sampler on or off.
MMUNE_VALUE_SAMPLE_INTERVAL_SECONDSOptional300Seconds between value drift samples.
MMUNE_VALUE_DRIFT_TABLES_PER_CYCLEOptional8Tables sampled per integration per cycle. Each is a read-only aggregate query on the monitored database. The value must be a positive whole number.
MMUNE_VALUE_DRIFT_WARMUP_SAMPLESOptional5Samples a field must collect before mmune evaluates it.
MMUNE_VALUE_DRIFT_SIGMAOptional3.0Deviation, in standard deviations, that counts as out of range for a numeric field.
MMUNE_VALUE_DRIFT_SIGMA_CRITICALOptional6.0Deviation that raises a finding to critical.
MMUNE_VALUE_DRIFT_VOCAB_SHAREOptional0.05Share of sampled rows with previously unseen category values that triggers a vocabulary-break finding.
MMUNE_VALUE_DRIFT_VOCAB_SHARE_CRITICALOptional0.5Share that raises the finding to critical.
MMUNE_VALUE_DRIFT_NULL_RATE_DELTAOptional0.2Absolute rise in the share of empty values, compared with the baseline, that counts as a spike.
MMUNE_VALUE_DRIFT_NULL_RATE_DELTA_CRITICALOptional0.5Rise that raises the finding to critical.
MMUNE_VALUE_DRIFT_BOUNDSOptionalunsetJSON map of schema.table.column to [low, high] numeric bounds, for example {"public.orders.amount": [0, 100000]}. Malformed JSON is ignored and a warning is logged.
MMUNE_DRIFT_REPORTS_RETENTION_DAYSOptional90Days drift reports are kept.

Staleness and pipelines ​

VariableRequiredDefaultWhat it does
MMUNE_STALENESS_SAMPLE_ENABLEDOptionaltrueTurns on detection of tables whose row count stops changing, for PostgreSQL and MySQL.
MMUNE_STALENESS_SAMPLE_INTERVAL_SECONDSOptional300Seconds between staleness samples.
MMUNE_STALENESS_AFTER_SECONDSOptional900How long a row count may stay flat before the table is reported as stale.
MMUNE_FLOW_SAMPLE_ENABLEDOptionaltrueTurns the TIBCO flow sampler on or off.
MMUNE_FLOW_SAMPLE_INTERVAL_SECONDSOptional120Seconds between TIBCO flow samples.
MMUNE_KAFKA_FLOW_SAMPLE_ENABLEDOptionaltrueTurns the Kafka consumer-lag sampler on or off.
MMUNE_KAFKA_FLOW_SAMPLE_INTERVAL_SECONDSOptional120Seconds between Kafka samples.
MMUNE_KAFKA_LAG_THRESHOLDOptional1000Lag at or above which a consumer group counts as stuck.
MMUNE_KAFKA_MAX_GROUPS_PER_CYCLEOptional20Consumer groups sampled per cycle.
MMUNE_AIRFLOW_RUN_SAMPLE_ENABLEDOptionaltrueTurns the Airflow run sampler on or off.
MMUNE_AIRFLOW_RUN_SAMPLE_INTERVAL_SECONDSOptional120Seconds between Airflow samples.
MMUNE_AIRFLOW_CONSECUTIVE_FAILURESOptional3Consecutive failed runs that raise a finding.
MMUNE_AIRFLOW_STUCK_MULTIPLEOptional3.0A run counts as stuck when it takes longer than this multiple of its typical duration.

Scans, incidents and containment ​

VariableRequiredDefaultWhat it does
MMUNE_ADVISOR_RESCAN_HOURSOptional24Hours between full-estate advisor rescans. 0 turns them off.
MMUNE_SECURITY_SCAN_INTERVAL_HOURSOptional24Hours between scheduled security scans.
MMUNE_AUTO_SCAN_ENABLEDOptionaltrueTurns automatic security scans on or off.
MMUNE_AUTO_SCAN_STARTUP_DELAY_SECONDSOptional120Delay before the first automatic scan after the backend starts.
MMUNE_AUTO_SCAN_DEBOUNCE_SECONDSOptional300Quiet period before a scan triggered by a change runs.
MMUNE_AUTO_SCAN_DEBOUNCE_MAX_SECONDSOptional900Longest a scan triggered by a change can be deferred.
MMUNE_INCIDENT_CORRELATION_WINDOW_HOURSOptional24Window in hours used to group alerts into one incident. The minimum is 1.
MMUNE_INCIDENT_ANALYSIS_MODEOptionalon_demandOne of off, on_demand or auto_on_open.
MMUNE_CONTAINMENT_MODEOptionaloffOne of off, observe or active. A value saved in the console takes precedence over this variable.
MMUNE_CONTAINMENT_SEVERITY_THRESHOLDOptionalcriticalLowest severity that triggers containment.
MMUNE_IMPACT_COST_PER_RECORDOptionalunsetCost of one affected record, used in impact reports. Values saved in the console take precedence.
MMUNE_IMPACT_COST_PER_HOUROptionalunsetCost of one hour of disruption, used in impact reports. Values saved in the console take precedence.

Source-system connectors ​

These settings apply to specific kinds of monitored systems. Set the ones that match your estate and leave the rest alone. Per-system details such as host, user and password normally go in your credential profile file rather than here.

VariableRequiredDefaultWhat it does
MMUNE_HANA_SCHEMASOptionalthe profile's database fieldComma-separated SAP HANA schemas to read. Point it at your application schema, not the system schema.
MMUNE_HANA_TENANTOptionalthe profile valueHANA tenant database name.
MMUNE_HANA_ENCRYPTOptionaltrueSet to false, 0 or no for a HANA system that has no TLS.
MMUNE_HANA_SSL_VALIDATEOptionaltrueWhether mmune validates the HANA server certificate. A value in the profile wins over this variable.
MMUNE_HANA_CA_CERTOptionalunsetPath inside the container of the certificate authority file used to validate the HANA certificate.
MMUNE_ORACLE_SERVICERequired if the profile does not give onethe profile valueOracle service name.
MMUNE_ORACLE_SCHEMASOptionalthe profile's schemas fieldComma-separated Oracle schemas to read. Use it to limit load on large estates.
MMUNE_POSTGRES_ROW_COUNT_EXACT, MMUNE_MYSQL_ROW_COUNT_EXACT, MMUNE_MONGODB_ROW_COUNT_EXACTOptionaloffUse exact row counts instead of the database's own estimates. Exact counts put more load on the monitored database.
MMUNE_RABBITMQ_MGMT_PORTOptional15672Management API port used when monitoring RabbitMQ.
MMUNE_TIBCO_TARGETSOptionalemptyComma-separated host[:ssh_port] list, each registered as a TIBCO integration. TIBCO is reached over SSH, so port scanning does not find it.
MMUNE_TIBCO_SSH_KEY_PATHOptionalunsetPath inside the container of the SSH private key used to collect TIBCO data. A key set in the profile wins.
MMUNE_TIBCO_KNOWN_HOSTSOptionalunsetPath inside the container of the known_hosts file. A host key that is not listed is rejected, not added automatically.
MMUNE_TIBCO_ELK_CA_CERTOptionalunsetCertificate authority file for TIBCO's ELK log endpoint.
MMUNE_TIBCO_EMS_ADMIN_USER, MMUNE_TIBCO_EMS_ADMIN_PASSWORDOptionalunsetCredentials for the EMS administration tool, used when the profile does not set them.

Alerts and notifications ​

For each channel, mmune uses the first match of a channel configuration saved in the console, then the environment, then the built-in default. Most channels are on by default, and ServiceNow is off. To turn a channel on or off, set MMUNE_NOTIFICATION_<CHANNEL>_ENABLED, where the channel is SLACK, WEBHOOK, PAGERDUTY, SERVICENOW, TEAMS or EMAIL_DIGEST.

VariableRequiredDefaultWhat it does
MMUNE_SLACK_WEBHOOK_URLOptionalunsetSlack incoming webhook URL.
MMUNE_TEAMS_WEBHOOK_URLOptionalunsetMicrosoft Teams webhook URL.
MMUNE_PAGERDUTY_ROUTING_KEYOptionalunsetPagerDuty Events API v2 routing key.
MMUNE_ALERT_WEBHOOK_URLOptionalunsetAddress of a generic webhook that receives alerts.
MMUNE_ALERT_WEBHOOK_AUTH_TOKENOptionalunsetToken sent to the generic webhook. Without it, alerts are posted without authentication.
MMUNE_ALERT_WEBHOOK_AUTH_HEADEROptionalAuthorizationName of the header that carries the token.
MMUNE_SMTP_HOSTOptionalunsetSMTP server for the email digest. The digest also needs recipients.
MMUNE_SMTP_TOOptionalunsetComma-separated recipients. Without recipients the digest is not configured.
MMUNE_SMTP_FROMOptionalmmune@localhostSender address.
MMUNE_SMTP_PORTOptional587SMTP port.
MMUNE_SMTP_USE_TLSOptionaltrueUse STARTTLS.
MMUNE_SMTP_USER, MMUNE_SMTP_PASSWORDOptionalunsetSMTP credentials.
MMUNE_EMAIL_DIGEST_INTERVAL_HOURSOptional24Hours between digests. The minimum is 0.1.
MMUNE_ALERT_MIN_SEVERITYOptionalno minimumDrops alerts below this severity. Accepts info, low, warning, medium, high and critical. An unrecognized value means no minimum.
MMUNE_ALERT_RETRY_MAXOptional3Delivery attempts per channel.
MMUNE_ALERT_DEDUP_WINDOWOptionaloffSeconds within which a repeat of the same alert is dropped.
MMUNE_ALERT_CIRCUIT_FAILURESOptional5Consecutive failures that pause a channel.
MMUNE_ALERT_CIRCUIT_RESET_SECONDSOptional60Cooldown before mmune tries a paused channel again.
MMUNE_ALERT_MAX_INFLIGHT_PER_CHANNELOptional4Deliveries allowed at the same time per channel.

Backup ​

VariableRequiredDefaultWhat it does
MMUNE_BACKUP_RETENTIONOptional14Number of backups the backup script from your package keeps.
MMUNE_BACKUP_PASSPHRASEOptionalunsetStrongly recommended. Encrypts the backup archive. Choose a strong value and store it apart from the backups.