Skip to main content

Configuration Reference

Merlon is configured with environment variables. Copy .env.example to .env for local development; do not use its credentials or secrets in production.

Environment variables​

VariableDefaultProduction guidance
MERLON_ENVdevelopmentSet to production.
MERLON_MODEallapi owns HTTP/realtime work, worker owns recovery/TM batch/backtests, all runs both.
MERLON_HTTP_ADDR:8080Bind behind a TLS-terminating reverse proxy.
MERLON_WORKER_HTTP_ADDR:8081Control/health listener used when MERLON_MODE=worker.
MERLON_WORKER_CONCURRENCY4Worker evaluation concurrency; keep bounded to the database/CPU budget.
MERLON_BACKTEST_QUEUE_TIMEOUT10mMaximum time an accepted backtest may remain queued. On expiry the job becomes failed with a retryable operator-facing reason.
MERLON_DATABASE_URLunsetUse TLS (sslmode=require or stronger) and a least-privilege application role.
MERLON_DATABASE_STARTUP_TIMEOUT30sMaximum time the API waits for the configured database to accept connections during startup.
MERLON_BUILD_VERSIONdevCompose build version embedded in the System status and image metadata.
MERLON_BUILD_REVISIONunsetFull source commit embedded in the Compose image; release acceptance must provide the exact 40-character SHA.
MERLON_BUILD_BUILT_ATunsetUTC build timestamp embedded in the Compose image.
MERLON_BACKUP_DATABASE_URLunsetDedicated read-only backup connection used only by make backup. Grant the documented existing/future table and sequence read privileges; never substitute a serving or schema-owner URL.
MERLON_MIGRATION_DATABASE_URLunsetSeparate schema/object-owner connection used by make migrate, make restore, and make audit-harden. This role must manage and have CREATE on the target public schema. When another role owns a fresh restore database, its owner must transfer public to this role and pre-grant direct database CONNECT to both this role and the application role. Never substitute the serving-role URL.
MERLON_MIGRATION_BASELINEunsetExplicit last-applied migration filename for a pre-ledger database; never inferred automatically.
MERLON_MIGRATIONS_DIRmigrationsMigration command only; directory containing versioned SQL migrations. The --migrations-dir flag takes precedence.
MERLON_ENCRYPTION_KEY_RINGunsetRequired for production PII protection. Use the documented key-ring format accepted by merlon-keyrotate; loss of every referenced key makes historical encrypted values unrecoverable. Back up keys through a protected KMS or secret manager.
MERLON_INBOUND_WEBHOOK_SECRETunsetHMAC secret for durable customer/transaction push webhooks. Keep it in a secret manager; inbound endpoints reject requests while it is unset.
MERLON_JWT_PRIVATE_KEY_FILE / MERLON_JWT_PUBLIC_KEY_FILEunsetUse an RS256 key pair for local-user authentication.
MERLON_JWT_SECRETunsetDevelopment fallback only. Do not set in production when using local-user authentication.
MERLON_BOOTSTRAP_TOKENunsetOne-time setup secret. Rotate or remove immediately after the first administrator/API key is created.
MERLON_POSTGRES_PASSWORDunsetCompose-only development password. Use a secret manager in production.
MERLON_API_HOST_PORT8080Compose-only host port for the API. The standard topology binds it on the host; the demo topology limits it to 127.0.0.1. The container always listens on 8080.
MERLON_DB_HOST_PORT5432Compose test overlay only. Publishes PostgreSQL on 127.0.0.1; the standard and demo topologies do not publish a database host port.
MERLON_OPERATOR_CONTENT_PATH./operator-contentCompose-only host directory mounted read-only by the standard topology. Store reviewed CDD, transaction-monitoring, and screening content under this root.
MERLON_AUTH_ENABLEDfalseMust be true in production.
MERLON_ENGINE_REQUIREDfalseSet true when monitoring must not run without a loaded native engine. The standard Compose topology sets this automatically.
MERLON_SEEDfalseDevelopment/demo data only; must be false in production.
MERLON_DEMO_DATA_DIRunsetDirectory holding a full generated demo dataset, loaded when MERLON_SEED is enabled. Falls back to the built-in sample if the directory is incomplete. Development/demo only.
MERLON_CONFIG_PATHconfig.yamlPath to application configuration.
MERLON_CACHE_BACKENDmemorySelect the configured cache backend.
MERLON_EVENT_BUSpg_notifyEvent bus driver used with PostgreSQL.
MERLON_RATE_LIMIT0Optional per-process requests per minute per resolved client IP. Use only as defense in depth; enforce deployment-wide limits at the trusted ingress. In production, a non-zero value requires MERLON_TRUSTED_PROXY_CIDRS.
MERLON_TRUSTED_PROXY_CIDRSunsetComma-separated, narrow CIDRs of reverse proxies allowed to supply X-Forwarded-For. Untrusted peers and malformed trusted-side hops fall back to the direct peer address; /0 is rejected. Configure this even with the application limiter disabled when audit records need the original client IP.
MERLON_ADAPTER_CONFIG_PATHunsetPath to an operator-managed adapter configuration.
MERLON_CDD_REVIEW_POLICY_PATHcontent/cdd_review_policy_v1.yamlVersioned CDD periodic-review schedule. Keep the policy file under change control; its digest is exposed in system status.
MERLON_UI_DIRunsetOptional directory containing the built UI.
MERLON_SCREENING_IMPORT_ENABLEDfalseEnable external sanctions-list imports only with approved endpoints.
MERLON_SCREENING_RESCREEN_ENABLEDfalseEnable periodic customer rescreening.
MERLON_SCREENING_IMPORT_INTERVAL24hScreening-list import interval.
MERLON_SCREENING_CHECK_INTERVAL1hRescreening interval.
MERLON_SCREENING_OFAC_URL / MERLON_SCREENING_EU_URLunsetApproved OFAC/EU list endpoints.
MERLON_SCREENING_UN_URL / MERLON_SCREENING_MOF_URLunsetApproved UN/MOF list endpoints.
MERLON_SCREENING_PEP_URLunsetApproved PEP provider endpoint.
MERLON_SMTP_HOST / MERLON_SMTP_PORTunset / 587SMTP endpoint for notifications; configure TLS and credentials.
MERLON_SMTP_USERNAME / MERLON_SMTP_PASSWORDunsetSMTP credentials; use a secret manager.
MERLON_SMTP_FROM / MERLON_SMTP_TOunsetNotification sender and comma-separated recipients.
MERLON_SMTP_USE_TLSfalseEnable TLS for SMTP.
MERLON_NOTIFY_ROUTING_PATHunsetOptional notification routing YAML path.
MERLON_PUBLIC_URLunsetPublic base URL used in notification links.
MERLON_WHITELIST_MAX_VALID_DAYS365Maximum whitelist validity period.
MERLON_EDD_STAGE2_DAYS / MERLON_EDD_STAGE3_DAYS60 / 90EDD escalation thresholds.
MERLON_TM_SCENARIOS_PATHtm_scenariosStore the directory in controlled source management. Runtime digests identify loaded content but do not authorize changes.
MERLON_OPERATOR_TEAMSunsetComma-separated durable assignment-team directory. Queue rows are never scanned to infer teams; authenticated assignment requires a configured value.
MERLON_CASE_PRIORITY_PATHcontent/case_priority_v1.yamlVersioned YAML mapping from persisted CDD tier/score to case priority.
MERLON_KYC_REQUIRED_FIELDS_PATHcontent/kyc_required_fields_v1.yamlVersioned YAML naming the identity fields each customer type must carry. enforcement: warn reports a gap without refusing the write; reject refuses it.
MERLON_EDD_POLICY_PATHcontent/edd_policy_v1.yamlVersioned YAML holding the whole EDD stage schedule, due boundary, completion requirements, and tier-downgrade behaviour. Supersedes MERLON_EDD_STAGE2_DAYS / MERLON_EDD_STAGE3_DAYS.
MERLON_SLA_POLICY_PATHcontent/sla_policy_v1.yamlVersioned YAML holding the optional SLA deadline rules. When unset or empty, SLA reporting remains not_configured rather than inventing a due date.
MERLON_CDD_RULE_SELECTION_PATHcontent/cdd_rule_selection_v1.yamlVersioned YAML mapping customer type, product, and jurisdiction to the applicable CDD rule set, so selection is configuration rather than list order.
MERLON_TRAVEL_RULE_POLICY_PATHcontent/travel_rule_v1.yamlVersioned YAML holding the Travel Rule threshold, covered activity, required evidence, exemption reason codes, and whether a conflicting caller assertion is recorded or rejected.
MERLON_SCREENING_READINESS_PATHcontent/screening_readiness_v1.yamlVersioned YAML naming the expected watchlist sources, their freshness windows, and whether an unready required source marks runs degraded or blocks them.
MERLON_CDD_WEIGHTS_PATHcdd_weights.yamlNative Go CDD rule root; pin and review content changes.
MERLON_COUNTRY_RISK_PATHunsetOptional native Go country-risk table.
MERLON_SCREENING_LISTS_PATHscreening_listsNative Go last-good screening-list snapshot root.
MERLON_SCREENING_THRESHOLDengine defaultName-match score, 0–1, at or above which a screening hit is raised. Lowering it raises recall and review volume. Values outside the range, or that do not parse, are ignored and leave the default in force. Changing it alters detection sensitivity and should follow the same review as a rule change.
MERLON_TM_BASE_CURRENCYJPYInterim PH9 invariant: mixed/non-base TM aggregation is fail-alerted to PENDING_REVIEW; full FX/decimal semantics are PH10.
MERLON_REALTIME_MONITOR_TIMEOUT30sMaximum synchronous history-loading and realtime-monitoring duration before fail-alert queueing.
MERLON_TM_BATCH_SCHEDULE02:00Daily HH:MM time for transaction-monitoring batch evaluation.
MERLON_TM_BATCH_TIMEZONElocal timezoneSet an IANA timezone explicitly in production.
MERLON_LOG_LEVELinfoKeep info or stricter; do not use debug logging for sensitive workloads.

The native Go engine also loads CDD weights and screening content from operator-supplied paths. Those files are outside the database audit trail. Control them through source control, change approval, access control, backup, and deployment procedures. See ADR-0012.

The standard Compose topology mounts the local operator-content/ directory at /app/operator-content and sets MERLON_ENGINE_REQUIRED=true. It points the three native roots at cdd_weights.yaml, tm_scenarios/, and screening_lists/ below that mount. A missing or invalid root does not make the process disappear: liveness remains available, while readiness and the system status page report the engine unavailable.

Encryption key rotation​

merlon-keyrotate accepts --key-ring-env (default MERLON_ENCRYPTION_KEY_RING) to select the environment variable containing the key-ring specification. Introduce a new active key while retaining old keys needed to decrypt existing data, deploy the updated ring, complete the migration, and only then retire the old key. Test restoration of both the application database and key material before relying on a backup.

Operational thresholds​

Sample TM and screening rules are examples, not production defaults. Choose thresholds from the deploying organization's risk assessment, test the change, and approve it through its rule-governance process. In particular, lowering a screening match threshold increases false positives; raising it increases missed-match risk. Under the fail-alert principle, resolve uncertainty toward additional review rather than suppressed alerts.