> ## 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 internal asynchronous balance-operation pipeline uses RabbitMQ when `RABBITMQ_TRANSACTION_ASYNC=true`. RabbitMQ also carries selected legacy outbound exchanges.

| 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_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/products/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, because 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        |

## 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.
