> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> Reference for Midaz ledger service environment variables — ports, TLS, deployment mode, and CRM or Fees settings for onboarding and transaction APIs.

This reference lists the environment variables that configure the **Midaz ledger service**. Midaz is the source-available (ELv2) double-entry engine. It serves the onboarding and transaction APIs on a single port. You set these variables at deploy time, through Helm values, Docker Compose, or your orchestrator's environment. A required variable that you do not set makes the server fail on startup.

Every Lerian product shares a set of configuration blocks: TLS posture, OpenTelemetry, Access Manager authentication, multi-tenancy, service discovery, and event streaming. The [BYOC configuration reference](/en/reference/byoc-configuration) documents these blocks. This page focuses on what is distinctive to the ledger.

<Note>
  Consolidation has landed. You deploy the **ledger** service (unified onboarding + transaction routes), and **CRM** and **Fees** are compiled into that same ledger process — the ledger binary reads the CRM and Fees variables below. Tracer lives in the same repository and ships as its own optional service. The former `onboarding`, `transaction`, and `mdz` components no longer exist as separate deployables. The Helm chart still carries a legacy standalone `crm` deployment, disabled by default.
</Note>

## Ports and health endpoints

The ledger runs one HTTP process. See the [health and readiness reference](/en/reference/health-and-readiness) for the probe contract.

| Surface                                                                        | Port variable                    | Default | Endpoints                        |
| ------------------------------------------------------------------------------ | -------------------------------- | ------- | -------------------------------- |
| Ledger HTTP (onboarding + transaction)                                         | `SERVER_PORT` / `SERVER_ADDRESS` | `3002`  | `/health`, `/readyz`, `/version` |
| CRM HTTP (legacy standalone deployment, disabled by default in the Helm chart) | `SERVER_PORT` / `SERVER_ADDRESS` | `4003`  | `/health`, `/readyz`             |

The ledger uses OTLP push for telemetry and does not expose a `/metrics` scrape endpoint.

## Deployment and TLS

| Variable             | Description                                                                                                                                                                                                                                                | Default | Required |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `DEPLOYMENT_MODE`    | Deployment flavor: `local`, `byoc`, or `saas`. In `saas`, TLS is mandatory for every dependency connection and the server refuses to start without it. In `byoc`, TLS is recommended and warned-on rather than enforced. Also tags the `/readyz` response. | `local` | No       |
| `ALLOW_INSECURE_TLS` | Bypass per-connection TLS enforcement on infrastructure DSNs. Leave unset or `false` in production; set `true` only for local plaintext infrastructure.                                                                                                    | `false` | No       |

## Application

| Variable                          | Description                                                                             | Default       | Required |
| --------------------------------- | --------------------------------------------------------------------------------------- | ------------- | -------- |
| `ENV_NAME`                        | Environment label (for example `development`, `staging`, `production`)                  | `development` | No       |
| `VERSION`                         | Service version tag                                                                     | varies        | No       |
| `LOG_LEVEL`                       | Log verbosity: `debug`, `info`, `warn`, or `error`                                      | `debug`       | No       |
| `MAX_PAGINATION_LIMIT`            | Maximum page size accepted by list endpoints                                            | `100`         | No       |
| `MAX_PAGINATION_MONTH_DATE_RANGE` | Maximum month span for date-range queries. The bundled example configuration ships `3`. | `1`           | No       |

## Database (PostgreSQL)

The ledger keeps two logical databases — `onboarding` and `transaction` — each with a primary and a replica connection block. The variables share one shape. Replace `{MODULE}` with `ONBOARDING` or `TRANSACTION`. Replica variables carry a `_REPLICA_` infix (for example `DB_ONBOARDING_REPLICA_HOST`).

| Variable                     | Description                                                                                                   | Default                      | Required |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- |
| `DB_{MODULE}_HOST`           | Primary PostgreSQL host                                                                                       | —                            | Yes      |
| `DB_{MODULE}_PORT`           | PostgreSQL port                                                                                               | —                            | Yes      |
| `DB_{MODULE}_USER`           | Database user                                                                                                 | —                            | Yes      |
| `DB_{MODULE}_PASSWORD`       | Database password. Sensitive — do not commit; supply through your secret store.                               | —                            | Yes      |
| `DB_{MODULE}_NAME`           | Database name                                                                                                 | `onboarding` / `transaction` | Yes      |
| `DB_{MODULE}_SSLMODE`        | libpq SSL mode: `disable`, `require`, `verify-ca`, or `verify-full`. Use `require` or stronger in production. | `disable`                    | No       |
| `DB_{MODULE}_MAX_OPEN_CONNS` | Maximum open connections in the pool                                                                          | `3000`                       | No       |
| `DB_{MODULE}_MAX_IDLE_CONNS` | Maximum idle connections in the pool                                                                          | `3000`                       | No       |

## Document store (MongoDB)

The MongoDB variables use one namespace per module: `MONGO_ONBOARDING_*`, `MONGO_TRANSACTION_*`, and — on the consolidated binary — `MONGO_CRM_*` and `MONGO_FEES_*`. All share one shape. Replace `{NS}` with the namespace. They may point at one MongoDB deployment (separate logical databases) or dedicated hosts.

| Variable                   | Description                                                            | Default             | Required |
| -------------------------- | ---------------------------------------------------------------------- | ------------------- | -------- |
| `MONGO_{NS}_HOST`          | MongoDB host                                                           | —                   | Yes      |
| `MONGO_{NS}_PORT`          | MongoDB port                                                           | —                   | Yes      |
| `MONGO_{NS}_USER`          | Database user                                                          | —                   | Yes      |
| `MONGO_{NS}_PASSWORD`      | Database password. Sensitive.                                          | —                   | Yes      |
| `MONGO_{NS}_NAME`          | Database name                                                          | namespace name      | Yes      |
| `MONGO_{NS}_URI`           | Connection scheme: `mongodb` or `mongodb+srv`                          | `mongodb`           | No       |
| `MONGO_{NS}_MAX_POOL_SIZE` | Maximum connection pool size                                           | `1000` (Fees `100`) | No       |
| `MONGO_{NS}_TLS_CA_CERT`   | Base64-encoded PEM CA certificate for TLS (for example AWS DocumentDB) | —                   | No       |
| `MONGO_{NS}_PARAMETERS`    | Extra connection-string parameters                                     | —                   | No       |

## Cache (Redis / Valkey)

| Variable                         | Description                                                    | Default | Required |
| -------------------------------- | -------------------------------------------------------------- | ------- | -------- |
| `REDIS_HOST`                     | Redis/Valkey host and port                                     | —       | Yes      |
| `REDIS_PASSWORD`                 | Authentication password. Sensitive.                            | —       | No       |
| `REDIS_TLS`                      | Enable TLS for the connection                                  | `false` | No       |
| `REDIS_CA_CERT`                  | Base64-encoded PEM CA certificate for TLS                      | —       | No       |
| `REDIS_DB`                       | Logical database index                                         | `0`     | No       |
| `REDIS_PROTOCOL`                 | RESP protocol version                                          | `3`     | No       |
| `REDIS_POOL_SIZE`                | Connection pool size                                           | `10`    | No       |
| `REDIS_MASTER_NAME`              | Sentinel master name (Sentinel deployments)                    | —       | No       |
| `REDIS_USE_GCP_IAM`              | Authenticate to GCP Memorystore with IAM instead of a password | `false` | No       |
| `REDIS_SERVICE_ACCOUNT`          | GCP service account for IAM auth                               | —       | No       |
| `GOOGLE_APPLICATION_CREDENTIALS` | Path to GCP credentials file for IAM auth                      | —       | No       |

## Message broker (RabbitMQ)

The transaction module uses RabbitMQ for balance operations and event fan-out.

| Variable                              | Description                                                                                                                                                                                    | Default | Required |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `RABBITMQ_HOST`                       | Broker host                                                                                                                                                                                    | —       | Yes      |
| `RABBITMQ_PORT_HOST`                  | **AMQP port** used to dial the broker. Despite the name, this is the port the connection string uses (`3003` in the bundled infrastructure).                                                   | —       | Yes      |
| `RABBITMQ_PORT_AMQP`                  | **Management/HTTP port** reported on the health-check connection (`3004` in the bundled infrastructure). Despite the name, it is not used to dial AMQP.                                        | —       | No       |
| `RABBITMQ_URI`                        | Connection scheme: `amqp` or `amqps`. Use `amqps` in production.                                                                                                                               | `amqp`  | No       |
| `RABBITMQ_DEFAULT_USER`               | Publisher user                                                                                                                                                                                 | —       | Yes      |
| `RABBITMQ_DEFAULT_PASS`               | Publisher password. Sensitive.                                                                                                                                                                 | —       | Yes      |
| `RABBITMQ_CONSUMER_USER`              | Consumer user                                                                                                                                                                                  | —       | Yes      |
| `RABBITMQ_CONSUMER_PASS`              | Consumer password. Sensitive.                                                                                                                                                                  | —       | Yes      |
| `RABBITMQ_VHOST`                      | Virtual host                                                                                                                                                                                   | `/`     | No       |
| `RABBITMQ_NUMBERS_OF_WORKERS`         | Consumer concurrency                                                                                                                                                                           | `5`     | No       |
| `RABBITMQ_NUMBERS_OF_PREFETCH`        | Consumer prefetch count                                                                                                                                                                        | `10`    | No       |
| `RABBITMQ_TRANSACTION_ASYNC`          | Record transactions asynchronously through the broker                                                                                                                                          | `false` | No       |
| `RABBITMQ_TRANSACTION_EVENTS_ENABLED` | Publish transaction events. Any value other than `false` — including unset — enables publishing; set `false` explicitly to disable. The bundled example configuration ships `false`.           | enabled | No       |
| `RABBITMQ_OVERDRAFT_EVENTS_ENABLED`   | Publish overdraft events. Any value other than `false` — including unset — enables publishing; set `false` explicitly to disable. The bundled example configuration ships `false`.             | enabled | No       |
| `AUDIT_LOG_ENABLED`                   | Append transactions to an audit log exchange. Any value other than `false` — including unset — enables it; set `false` explicitly to disable. The bundled example configuration ships `false`. | enabled | No       |

## Throughput

| Variable                            | Description                                                                                                                                                            | Default            | Required |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------- |
| `BULK_RECORDER_ENABLED`             | Batch transaction writes for high-throughput ingestion                                                                                                                 | `true`             | No       |
| `BULK_RECORDER_SIZE`                | Batch size trigger. When unset, Midaz derives it from `RABBITMQ_NUMBERS_OF_WORKERS` × `RABBITMQ_NUMBERS_OF_PREFETCH` (50 with the default worker and prefetch values). | workers × prefetch | No       |
| `BULK_RECORDER_FLUSH_TIMEOUT_MS`    | Flush interval for the batch recorder (milliseconds)                                                                                                                   | `100`              | No       |
| `BULK_RECORDER_MAX_ROWS_PER_INSERT` | Maximum rows per batch insert                                                                                                                                          | `1000`             | No       |

## Tracer integration

The optional seam lets the ledger reserve spending limits against Tracer before it commits a transaction. Leave `TRACER_BASE_URL` unset to disable it.

| Variable               | Description                                                                   | Default | Required  |
| ---------------------- | ----------------------------------------------------------------------------- | ------- | --------- |
| `TRACER_BASE_URL`      | Tracer service URL; setting it enables the reservation client                 | —       | No        |
| `TRACER_TIMEOUT_MS`    | Reservation call deadline (milliseconds)                                      | `250`   | No        |
| `TRACER_TRANSPORT`     | Reservation transport: `grpc` or `rest`                                       | `grpc`  | No        |
| `TRACER_TLS_MODE`      | Seam security: `mesh` (default, TLS terminated by the service mesh) or `mtls` | `mesh`  | No        |
| `TRACER_TLS_CERT_FILE` | Client certificate PEM path (when `mtls`)                                     | —       | If `mtls` |
| `TRACER_TLS_KEY_FILE`  | Client private-key PEM path (when `mtls`). Sensitive.                         | —       | If `mtls` |
| `TRACER_TLS_CA_FILE`   | CA certificate PEM path (when `mtls`)                                         | —       | If `mtls` |

<Note>
  With `TRACER_BASE_URL` set, the seam uses the default `grpc` transport unless you set `TRACER_TRANSPORT=rest`. The gRPC transport requires the Tracer service to expose its reservation gRPC seam — set `TRACER_GRPC_PORT` on Tracer (see [Tracer environment variables](/en/tracer/tracer-environment-variables)). Under `TRACER_TLS_MODE=mtls`, you must set the client certificate, key, and CA paths above.
</Note>

## CRM and Fees

The ledger process reads these variables — CRM and Fees are compiled into the ledger binary. They protect account-holder PII and configure the field-encryption backend.

| Variable                     | Description                                                                             | Default | Required  |
| ---------------------------- | --------------------------------------------------------------------------------------- | ------- | --------- |
| `LCRYPTO_HASH_SECRET_KEY`    | 64-hex hashing key for holder PII. Sensitive — generate a unique value per environment. | —       | Yes (CRM) |
| `LCRYPTO_ENCRYPT_SECRET_KEY` | 64-hex encryption key for holder PII. Sensitive.                                        | —       | Yes (CRM) |
| `KMS_VENDOR`                 | Field-encryption backend: `none` or `hashicorp-vault`                                   | `none`  | No        |
| `KMS_VAULT_ADDR`             | Vault address (when `hashicorp-vault`)                                                  | —       | No        |
| `KMS_VAULT_AUTH_METHOD`      | Vault auth method: `token` or `approle`. Use `approle` in `byoc`/`saas`.                | `token` | No        |
| `KMS_VAULT_ROLE_ID`          | Vault AppRole role ID (when `approle`)                                                  | —       | No        |
| `KMS_VAULT_SECRET_ID`        | Vault AppRole secret ID (when `approle`). Sensitive.                                    | —       | No        |
| `DEFAULT_CURRENCY`           | Fallback fee currency (ISO 4217)                                                        | `USD`   | No        |

## Shared configuration backbone

The following blocks are identical across Lerian products. The [BYOC configuration reference](/en/reference/byoc-configuration) documents them in full. They default off. A single-tenant BYOC deployment can ignore all the optional ones.

* **Access Manager authentication** — `PLUGIN_AUTH_ENABLED`, `PLUGIN_AUTH_HOST`. Enable in production.
* **Multi-tenancy** — `MULTI_TENANT_*`. Off by default. Enables per-tenant database resolution.
* **Service discovery** — `SD_*` (Consul). Off by default.
* **Event streaming** — `STREAMING_*` (lib-streaming producer). Off by default on the ledger.
* **OpenTelemetry** — `ENABLE_TELEMETRY`, `OTEL_*`. Telemetry is OTLP push.
