Skip to main content
These are deploy-time variables set by DevOps; changes require a service restart. Runtime and business settings live in Configuration. In the tables below, the Default / Required column shows the default value; a bold qualifier (e.g. Required, Required in production, Required if enabled) marks variables that must be set. means no default.

Infrastructure configuration


This section is for DevOps teams. These variables are set at deployment time and require a service restart to take effect.

Application

VariableDefault / RequiredDescription
ENV_NAMEdevelopmentEnvironment (development, staging, production)
DEPLOYMENT_MODEbyocDeployment flavor. byoc = Bring Your Own Cloud (single-tenant, operator-managed). Toggles internal SaaS vs. BYOC behaviors.
SERVER_ADDRESS:8080HTTP server address and port
HTTP_BODY_LIMIT_BYTES1048576Maximum HTTP request body size in bytes
ALLOW_PRIVATE_UPSTREAMSfalse⚠️ Allow outbound adapters (CRM, Fees, JD, Midaz) to resolve to RFC1918/loopback IPs. Default false is fail-closed: production blocks DNS pivoting into private space. Enable in dev or in-cluster BYOC where upstreams legitimately live on private IPs. Cloud metadata endpoints stay blocked regardless of this flag.

TLS

VariableDefault / RequiredDescription
SERVER_TLS_CERT_FILEPath to TLS certificate file. Must be set together with SERVER_TLS_KEY_FILE.
SERVER_TLS_KEY_FILEPath to TLS private key file. Must be set together with SERVER_TLS_CERT_FILE.
TLS_TERMINATED_UPSTREAMfalseSet to true when TLS is terminated by a load balancer or reverse proxy.

Proxy headers

Used when the service runs behind a load balancer or reverse proxy. Required to extract the real client IP for rate limiting and audit logs.
VariableDefault / RequiredDescription
SERVER_PROXY_HEADERHTTP header carrying the real client IP (e.g. X-Forwarded-For, X-Real-IP). Empty disables proxy header parsing.
SERVER_TRUSTED_PROXIESRequired if proxy header setComma-separated list of trusted proxy IPs/CIDRs. Required when SERVER_PROXY_HEADER is set to prevent IP spoofing.

Authentication

This plugin delegates authorization to plugin-auth. Configure the connection with the variables below.
VariableDefault / RequiredDescription
PLUGIN_AUTH_ENABLEDfalseEnable authorization via plugin-auth. Set to true in production.
PLUGIN_AUTH_ADDRESSRequired if enabledURL of the plugin-auth service. Must use HTTPS in production.
When PLUGIN_AUTH_ENABLED=true, PLUGIN_AUTH_ADDRESS must use HTTPS in production environments. HTTP addresses are rejected at startup.

Test admin (non-production only)

BTF_TEST_ADMIN_ENABLED must remain false in production. It exposes test-only admin endpoints (e.g. POST /admin/test/circuit-breakers/reset) that are tenant-less and bypass production authentication. Enabled only by docker-compose mock-lane for E2E tests; any deployment with this flag true outside a sealed test network is a misconfiguration.
VariableDefault / RequiredDescription
BTF_TEST_ADMIN_ENABLEDfalse⚠️ Expose test-only admin endpoints. Must remain false in production.
BTF_TEST_ADMIN_TOKENRequired if admin enabledToken required when BTF_TEST_ADMIN_ENABLED=true. Sent in the X-Test-Admin-Token header. Intentionally separate from production auth (test-only surface, no tenant).

Idempotency

VariableDefault / RequiredDescription
IDEMPOTENCY_RETRY_WINDOW_SEC300Time window (in seconds) during which an idempotency key is considered valid.

Multi-tenancy

VariableDefault / RequiredDescription
MULTI_TENANT_ENABLEDfalseEnable infrastructure-level multi-tenancy with tenant-isolated databases.
ORGANIZATION_IDRequired (single-tenant + JD polling)Midaz organization UUID injected into background-worker context (TED IN poller, reconciliation) in single-tenant mode. Required when MULTI_TENANT_ENABLED=false and JD_POLLING_ENABLED=true. Ignored in multi-tenant mode, where per-tenant organization bindings are resolved by the tenant manager. HTTP requests always carry the organization in the X-Organization-Id header instead.
AWS_REGIONRequired if AWS secrets backendAWS region for per-tenant secret reads from Secrets Manager. Required when MULTI_TENANT_ENABLED=true and the secrets backend is AWS.
ORGANIZATION_IDSRequired in productionComma-separated list of Midaz organization UUIDs in the licensing scope. The license gateway validates LICENSE_KEY against these at startup. Also referenced under License.
MULTI_TENANT_URLRequired when enabledTenant Manager HTTP API URL.
MULTI_TENANT_REDIS_HOSTRedis host for Pub/Sub event-driven tenant discovery.
MULTI_TENANT_REDIS_PORT6379Redis port for Pub/Sub.
MULTI_TENANT_REDIS_PASSWORDRedis password for Pub/Sub.
MULTI_TENANT_REDIS_TLSfalseEnable TLS for Redis Pub/Sub connection.
MULTI_TENANT_REDIS_CA_CERTCA certificate for the multi-tenant Redis Pub/Sub TLS connection.
MULTI_TENANT_TIMEOUT30HTTP timeout in seconds for Tenant Manager API calls.
MULTI_TENANT_MAX_TENANT_POOLS100Maximum concurrent tenant database connection pools.
MULTI_TENANT_IDLE_TIMEOUT_SEC300Idle timeout in seconds before evicting a tenant pool.
MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD5Number of failures before the circuit breaker opens.
MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC30Recovery timeout in seconds for the circuit breaker.
MULTI_TENANT_SERVICE_API_KEYRequired when enabledAPI key for the Tenant Manager /settings endpoint.
MULTI_TENANT_CACHE_TTL_SEC120In-memory tenant config cache TTL in seconds. Hot-reloadable via systemplane API.
MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC30Async interval in seconds for revalidating pool settings. Bootstrap-only (not hot-reloadable).
BYOC single-tenant:
# Organization injected into background workers (required when JD polling is enabled)
ORGANIZATION_ID=<your-midaz-organization-uuid>
# Licensing scope validated against LICENSE_KEY in production
ORGANIZATION_IDS=<your-midaz-organization-uuid>
SaaS multi-tenant:
MULTI_TENANT_ENABLED=true
MULTI_TENANT_URL=http://tenant-manager:4003
MULTI_TENANT_SERVICE_API_KEY=your-api-key
MULTI_TENANT_REDIS_HOST=redis.example.com

PostgreSQL

VariableDefault / RequiredDescription
POSTGRES_HOSTlocalhost · RequiredPrimary PostgreSQL host.
POSTGRES_PORT5432Primary PostgreSQL port.
POSTGRES_USERplugin-br-bank-transfer · RequiredDatabase user.
POSTGRES_PASSWORDRequiredDatabase password. Required in production.
POSTGRES_DBplugin-br-bank-transfer · RequiredDatabase name.
POSTGRES_SSLMODErequireSSL mode. disable is rejected in production.
POSTGRES_MAX_OPEN_CONNS25Maximum open connections.
POSTGRES_MAX_IDLE_CONNS5Maximum idle connections.
POSTGRES_CONN_MAX_LIFETIME_MINS30Connection max lifetime in minutes.
POSTGRES_CONN_MAX_IDLE_TIME_MINS5Connection max idle time in minutes.
POSTGRES_CONNECT_TIMEOUT_SEC10Connection timeout in seconds.

PostgreSQL replica

Configure a read replica for query offloading. All fields fall back to primary values when unset.
VariableDefault / RequiredDescription
POSTGRES_REPLICA_HOSTReplica host. Unset = no replica.
POSTGRES_REPLICA_PORTReplica port.
POSTGRES_REPLICA_USERReplica user.
POSTGRES_REPLICA_PASSWORDReplica password.
POSTGRES_REPLICA_DBReplica database name.
POSTGRES_REPLICA_SSLMODEReplica SSL mode.

MongoDB

MongoDB is required for transfer audit event persistence. The service will not start without a valid MongoDB connection.
VariableDefault / RequiredDescription
MONGO_ENABLEDtrue · RequiredEnable MongoDB connection. Must be true in all environments.
MONGO_URIRequiredMongoDB connection string (e.g. mongodb://user:pass@host:27017). Must include credentials and TLS in production.
MONGO_DATABASERequiredMongoDB database name.
MONGO_MAX_POOL_SIZE25Maximum connection pool size.
MONGO_SERVER_SELECTION_TIMEOUT_MS3000Server selection timeout in milliseconds.
MONGO_HEARTBEAT_INTERVAL_MS10000Heartbeat interval in milliseconds.
MONGO_TLS_CA_CERTBase64-encoded CA certificate for MongoDB TLS. Use when MongoDB requires TLS with a custom CA (e.g. Atlas, private instances with self-signed certs).

Redis

VariableDefault / RequiredDescription
REDIS_HOSTlocalhost:6379 · RequiredRedis host and port.
REDIS_MASTER_NAMERedis Sentinel master name (if using Sentinel).
REDIS_PASSWORDRedis password (if auth enabled).
REDIS_DB0Redis database number.
REDIS_PROTOCOL3Redis protocol version (2 or 3).
REDIS_TLSfalseEnable TLS for Redis connections.
REDIS_CA_CERTCA certificate for Redis TLS.
REDIS_POOL_SIZE10Connection pool size.
REDIS_MIN_IDLE_CONNS2Minimum idle connections.
REDIS_READ_TIMEOUT_MS3000Read timeout in milliseconds.
REDIS_WRITE_TIMEOUT_MS3000Write timeout in milliseconds.
REDIS_DIAL_TIMEOUT_MS5000Dial timeout in milliseconds.
Redis is a mandatory dependency. If Redis is unavailable at startup or becomes unreachable at runtime, the service reports as DOWN to the orchestration readiness probe and stops accepting requests. Redis is required for idempotency key caching and duplicate detection.

JD SPB connection

These variables are required for BYOC deployments. In SaaS mode, Lerian manages the JD connection.
VariableDefault / RequiredDescription
JD_BASE_URLRequired for BYOCJD SPB API base URL.
JD_SOAP_PATH/soapJD SOAP endpoint path.
JD_LEGACY_CODERequired for BYOCJD legacy system code (max 10 chars).
JD_USER_CODERequired for BYOCJD user code (max 10 chars).
JD_PASSWORDRequired for BYOCJD password (encrypted at rest).
JD_PRIVATE_KEY_PEMRequired for BYOCRSA private key PEM content for XML signature.
JD_PRIVATE_KEY_PEM_FILEPath to a file containing the RSA private key PEM. Alternative to inlining the key in JD_PRIVATE_KEY_PEM; read at startup.
JD_PUBLIC_KEY_PEMPublic key PEM for validating signatures on JD responses.
JD_PRIVATE_KEY_KEYINFOXML <KeyInfo> block embedded in the SOAP signature (e.g. base64-encoded X509 cert). Required for the WS-Security envelope when JD demands certificate identification.
JD_CERT_PEMOptional PEM-encoded X.509 certificate paired with the JD signing key. Used only by the cert-expiry metrics gauge, not the signing path; a malformed PEM is a startup error.
JD_SIGNING_MODElocal_pemSOAP signing mode. local_pem signs locally with JD_PRIVATE_KEY_PEM; external_signer delegates to a remote service via JD_EXTERNAL_SIGNER_URL.
JD_EXTERNAL_SIGNER_URLRequired if JD_SIGNING_MODE=external_signerBase URL of the external signing service.
JD_EXTERNAL_SIGNER_AUTH_TOKENBearer token sent in the Authorization header for external-signer calls.
JD_EXTERNAL_SIGNER_TIMEOUT_MS5000Timeout (in milliseconds) for external-signer calls.
JD_SANDBOX_MODEfalseEnable JD sandbox mode. Rejected in production.

JD polling

VariableDefault / RequiredDescription
JD_POLLING_ENABLEDfalseEnable TED IN polling worker.
JD_POLL_INTERVAL_SECONDS60How often (in seconds) the plugin polls for incoming TEDs.
JD_POLLING_ENABLED defaults to false for safer deployments. In single-tenant mode, set ORGANIZATION_ID before enabling it — background workers inject it into context for downstream CRM/Midaz calls. In multi-tenant mode, the TED IN poller manager starts one poller per active tenant discovered through tenant-manager and resolves each tenant’s JD configuration through the tenant integration resolver.

External services (Midaz)

VariableDefault / RequiredDescription
MIDAZ_BASE_URLRequiredMidaz base service URL.
MIDAZ_TRANSACTION_URLRequiredMidaz transaction service URL.
MIDAZ_TIMEOUT_MS3000Midaz request timeout in milliseconds.
MIDAZ_MAX_RETRIES3Retry attempts on Midaz failure.
MIDAZ_AUTH_ENABLEDfalseEnable M2M authentication for Midaz.
MIDAZ_AUTH_ADDRESSRequired if enabledAuth service URL for Midaz M2M tokens.
MIDAZ_CLIENT_IDRequired if enabledOAuth client ID for Midaz M2M.
MIDAZ_CLIENT_SECRETRequired if enabledOAuth client secret for Midaz M2M.

External services (CRM)

VariableDefault / RequiredDescription
CRM_BASE_URLRequiredCRM service URL.
CRM_TIMEOUT_MS2000CRM request timeout in milliseconds.
CRM_MAX_RETRIES2Retry attempts on CRM failure.
CRM_AUTH_ENABLEDfalseEnable M2M authentication for CRM.
CRM_CLIENT_IDRequired if enabledOAuth client ID for CRM M2M.
CRM_CLIENT_SECRETRequired if enabledOAuth client secret for CRM M2M.

External services (Fees)

BTF_FEE_ENABLED is the master switch. When false (default), no Fees adapter is constructed and every transfer proceeds with fee=0 with no HTTP call. The other FEES_* variables only take effect when BTF_FEE_ENABLED=true.
VariableDefault / RequiredDescription
BTF_FEE_ENABLEDfalseMaster switch for plugin-fees integration. When false, no Fees adapter is built and all transfers run with fee=0 without HTTP calls. Operators running plugin-fees must set this to true explicitly.
FEES_BASE_URLRequired if enabledFees Engine service URL.
FEES_TIMEOUT_MS2000Fee request timeout in milliseconds.
FEES_MAX_RETRIES2Retry attempts on fee service failure.
FEES_AUTH_ENABLEDfalseEnable M2M authentication for Fees.
FEES_CLIENT_IDRequired if enabledOAuth client ID for Fees M2M.
FEES_CLIENT_SECRETRequired if enabledOAuth client secret for Fees M2M.

RabbitMQ

Transfer lifecycle events can be published to RabbitMQ for downstream consumers.
VariableDefault / RequiredDescription
RABBITMQ_ENABLEDfalseEnable transfer lifecycle event publishing.
RABBITMQ_URLRequired if enabledAMQP connection URL. Must use amqps:// outside development.
RABBITMQ_HEALTH_CHECK_URLHTTP(S) URL of the RabbitMQ management health endpoint. Hostname must match RABBITMQ_URL; must use https:// in production.
RABBITMQ_EXCHANGEbank_transfer.lifecycleExchange name for lifecycle events.
RABBITMQ_EVENT_SIGNING_SECRETRequired if enabledHMAC secret for signing published events. Minimum 32 characters.

Streaming outbox

The streaming subsystem publishes transfer events to a Redpanda/Kafka broker via a transactional outbox. It must be enabled for outbound webhook delivery to work (WEBHOOK_ENABLED=true requires STREAMING_ENABLED=true).
VariableDefault / RequiredDescription
STREAMING_ENABLEDfalseEnable the streaming outbox subsystem. Required for webhook delivery.
STREAMING_BROKERSRequired if enabledComma-separated list of Kafka/Redpanda broker addresses.
STREAMING_CLIENT_IDClient ID presented to the broker.
STREAMING_CLOUDEVENTS_SOURCERequired if enabledCloudEvents source attribute set on published events.
STREAMING_OUTBOX_DISPATCH_INTERVAL_SECONDS30Interval (in seconds) between outbox dispatch cycles. Must be > 0.
STREAMING_CB_FAILURE_RATIO0.5Circuit breaker failure ratio that trips the breaker (must be > 0 and ≤ 1).
STREAMING_CB_MIN_REQUESTS10Minimum requests in a window before the circuit breaker can trip.
STREAMING_CB_TIMEOUT_S30Circuit breaker recovery timeout in seconds.
STREAMING_CLOSE_TIMEOUT_S30Graceful shutdown timeout (in seconds) for the streaming producer.

Webhook delivery

Outbound webhook delivery requires both RabbitMQ and the streaming outbox to be enabled. The webhook worker consumes events from a RabbitMQ queue and delivers them to subscriber endpoints.
VariableDefault / RequiredDescription
WEBHOOK_ENABLEDfalseEnable outbound webhook delivery. Requires RABBITMQ_ENABLED=true and STREAMING_ENABLED=true.
WEBHOOK_SIGNING_SECRETRequired if enabledHMAC secret for signing webhook payloads. Minimum 32 characters.
WEBHOOK_BROKER_EVENT_SIGNING_SECRETSeparate HMAC secret for verifying broker events. Falls back to WEBHOOK_SIGNING_SECRET.
WEBHOOK_QUEUE_NAMEtransfer.webhook.deliveryRabbitMQ queue name for webhook events.
WEBHOOK_DLQ_NAMEtransfer.webhook.dlqDead-letter queue for failed webhook deliveries.
WEBHOOK_DLX_EXCHANGE_NAMEDead-letter exchange name. When empty, the worker derives <WEBHOOK_DLQ_NAME>.exchange. Override to centralize the DLX across plugins.
WEBHOOK_DLQ_MESSAGE_TTL_MS0x-message-ttl on the DLQ in milliseconds. 0 defers to the library default (7 days). Topology changes require deleting the existing DLQ before redeploy.
WEBHOOK_DLQ_MAX_LENGTH0Maximum DLQ message count. 0 defers to the library default (10000).
WEBHOOK_PREFETCH_COUNT20RabbitMQ prefetch count.
WEBHOOK_DELIVERY_CONCURRENCY8Maximum concurrent webhook deliveries per worker.

Telemetry (OpenTelemetry)

VariableDefault / RequiredDescription
ENABLE_TELEMETRYfalseEnable OpenTelemetry tracing and metrics.
OTEL_EXPORTER_OTLP_ENDPOINTlocalhost:4317OTel collector gRPC endpoint.
OTEL_TRACES_SAMPLER_ARGTrace sampling ratio (0.0–1.0). Unset uses the default sampler resolved at telemetry init: 0.1 in production, 1.0 elsewhere. Values outside (0,1] are clamped to 1.0 so misconfiguration cannot silently disable production tracing.
BTF_METRICS_PROMETHEUS_ENABLEDfalseExpose a dedicated Prometheus scrape endpoint for btf.* metrics. When true, the listener at BTF_METRICS_PROMETHEUS_ADDRESS is started.
BTF_METRICS_PROMETHEUS_ADDRESS127.0.0.1:9090Listen address for the Prometheus /metrics endpoint. Default binds to loopback so a misconfigured pod does not expose unauthenticated metrics to the cluster network. Override (e.g. 0.0.0.0:9090) only behind a NetworkPolicy or sidecar.

License

VariableDefault / RequiredDescription
LICENSE_KEYRequired in productionLicense key. Required in production environments.
LICENSE_SERVICE_ADDRESSLicense validation service URL.
ORGANIZATION_IDSRequired in productionSame variable as in Multi-tenancy. Comma-separated list of Midaz organization UUIDs in the licensing scope; the license gateway validates LICENSE_KEY against these at startup.

Encryption

Field-level encryption for sensitive data at rest. Each key must be a base64-encoded 32-byte AES-256 key. Leave empty to disable encryption for that field.
VariableDefault / RequiredDescription
JD_INCOMING_RAW_XML_ENCRYPTION_KEYAES-256 key for encrypting incoming JD XML payloads.
RECIPIENT_DETAILS_ENCRYPTION_KEYAES-256 key for encrypting recipient details at rest.