> ## 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 Tracer environment variables covering ports, TLS, PostgreSQL, authentication, RI permission declaration, background workers, CEL cost limits, and reservation gRPC.

This reference lists the environment variables used to configure **Tracer**, the real-time spending-control and transaction-risk service. You set these at deploy time, through Helm values, Docker Compose, or your orchestrator's environment. Variables marked as required cause the server to fail on startup if not set.

For the configuration blocks that every Lerian product shares, see the [BYOC configuration reference](/en/reference/byoc-configuration). Those blocks cover TLS posture, OpenTelemetry, Access Manager authentication, multi-tenancy, service discovery, and event streaming. This page focuses on what is distinctive to Tracer.

## Ports and health endpoints

See the [health and readiness reference](/en/reference/health-and-readiness) for the probe contract.

| Surface                        | Port variable                    | Default     | Endpoints                                    |
| ------------------------------ | -------------------------------- | ----------- | -------------------------------------------- |
| REST + health                  | `SERVER_PORT` / `SERVER_ADDRESS` | `4020`      | `/health`, `/readyz`, `/version`, `/metrics` |
| Reservation gRPC seam (opt-in) | `TRACER_GRPC_PORT`               | unset (off) | gRPC reserve / confirm / release             |

## Deployment and TLS

| Variable             | Description                                                                                                                                                                                                                                                                                                                              | Default | Required |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `DEPLOYMENT_MODE`    | Deployment flavor: `local`, `byoc`, or `saas`. In `saas`, TLS on the PostgreSQL connection is validated at boot and the server refuses to start without it. In `byoc` and `local`, that boot-time check is skipped, but per-connection TLS enforcement still applies unless `ALLOW_INSECURE_TLS=true`. Also tags the `/readyz` response. | `local` | No       |
| `ALLOW_INSECURE_TLS` | Bypass per-connection TLS enforcement on infrastructure DSNs. Leave unset or `false` in production.                                                                                                                                                                                                                                      | `false` | No       |

## Application

| Variable               | Description                                                                                        | Default | Required |
| ---------------------- | -------------------------------------------------------------------------------------------------- | ------- | -------- |
| `VERSION`              | Service version tag                                                                                | varies  | No       |
| `LOG_LEVEL`            | Log verbosity: `debug`, `info`, `warn`, or `error`                                                 | `debug` | No       |
| `CEL_COST_LIMIT`       | Maximum evaluation cost for a single CEL rule expression                                           | `10000` | No       |
| `OPENAPI_DOCS_ENABLED` | Serve the OpenAPI 3.1 spec and interactive Scalar docs at `/v1/openapi.{json,yaml}` and `/v1/docs` | `false` | No       |

## Rule evaluation

| Variable                         | Description                                                                                                                                                                                                                                                                                        | Default | Required |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `DEFAULT_DECISION_WHEN_NO_MATCH` | Decision returned when no rule matches a transaction. Only `ALLOW` (fail-open) and `DENY` (fail-closed) are accepted — `REVIEW` is deliberately rejected, and any other value fails the service at boot. Leaving it unset keeps `ALLOW` and logs a startup warning.                                | `ALLOW` | No       |
| `MAX_RULES_PER_REQUEST`          | Ceiling on how many active rules are evaluated in a single validation. When more rules apply, the excess is truncated (a warning is logged) and the response reports `totalRulesLoaded` with `truncated: true`. Must be positive and at most `100000`; an invalid value fails the service at boot. | `1000`  | No       |

## Authentication and request handling

| Variable                          | Description                                                                                                                                                                                               | Default                              | Required                        |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ------------------------------- |
| `API_KEY_ENABLED`                 | Enforce API-key authentication                                                                                                                                                                            | `false`                              | No                              |
| `API_KEY`                         | API key for request authentication. Sensitive — use at least 32 characters in production.                                                                                                                 | —                                    | Yes (if `API_KEY_ENABLED=true`) |
| `API_KEY_ENABLED_ONLY_VALIDATION` | Validate-only mode: check keys without hard-enforcing them                                                                                                                                                | `false`                              | No                              |
| `API_KEY_LABEL`                   | Audit actor identifier recorded for the API-key principal                                                                                                                                                 | `tracer-default`                     | No                              |
| `CORS_ALLOWED_ORIGINS`            | Allowed CORS origins (CSV). When unset or empty, cross-origin requests are not allowed; set an explicit allow-list in production. The explicit value `*` is rejected at boot when `API_KEY_ENABLED=true`. | — (no cross-origin requests allowed) | No                              |
| `TRUSTED_PROXY_CIDRS`             | Trusted proxy CIDRs for `X-Forwarded-For` parsing. Set when running behind a load balancer.                                                                                                               | — (uses peer IP)                     | No                              |

## RI permission declaration

| Variable                  | Description                                                                                                                                                                                                 | Default | Required               |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------- |
| `IDP_DECLARATION_ENABLED` | Publish Tracer's permission declaration to the identity service at boot. This integration is optional and fail-open: a publish or configuration failure logs a warning and Tracer continues serving.        | `false` | No                     |
| `IDP_HOST`                | Absolute URL of the identity service (distinct from the Access Manager address in `PLUGIN_AUTH_ADDRESS`). When declaration is enabled in `saas`, an explicit `http://` URL makes boot fail; use `https://`. | —       | No (needed to publish) |
| `IDP_M2M_CLIENT_ID`       | Client ID used for the declaration's machine-to-machine token.                                                                                                                                              | —       | No (needed to publish) |
| `IDP_M2M_CLIENT_SECRET`   | Secret used for the declaration's machine-to-machine token. Sensitive.                                                                                                                                      | —       | No (needed to publish) |

## Database (PostgreSQL)

Tracer stores rules and usage counters in its own `tracer` database on the shared Midaz PostgreSQL primary. A dedicated migration-runner image applies the schema migration before the application starts. The service boots against an already-migrated schema and does not run migrations in-process.

| Variable      | Description                                                                                                   | Default   | Required |
| ------------- | ------------------------------------------------------------------------------------------------------------- | --------- | -------- |
| `DB_HOST`     | PostgreSQL host                                                                                               | —         | Yes      |
| `DB_PORT`     | PostgreSQL port                                                                                               | —         | Yes      |
| `DB_USER`     | Database user                                                                                                 | —         | Yes      |
| `DB_PASSWORD` | Database password. Sensitive.                                                                                 | —         | Yes      |
| `DB_NAME`     | Database name                                                                                                 | —         | Yes      |
| `DB_SSL_MODE` | libpq SSL mode: `disable`, `require`, `verify-ca`, or `verify-full`. Use `require` or stronger in production. | `disable` | No       |

## Background workers

| Variable                                | Description                                                                                        | Default | Required |
| --------------------------------------- | -------------------------------------------------------------------------------------------------- | ------- | -------- |
| `CLEANUP_WORKER_ENABLED`                | Run the expired usage-counter cleanup worker                                                       | `false` | No       |
| `CLEANUP_INTERVAL_HOURS`                | Cleanup interval (hours). The retention window itself is fixed at 90 days and is not configurable. | `24`    | No       |
| `RULE_SYNC_POLL_INTERVAL_SECONDS`       | Rule-cache sync poll interval (seconds)                                                            | `10`    | No       |
| `RULE_SYNC_STALENESS_THRESHOLD_SECONDS` | Rule-cache staleness threshold (seconds)                                                           | `50`    | No       |
| `RULE_SYNC_OVERLAP_BUFFER_SECONDS`      | Rule-cache sync overlap buffer (seconds)                                                           | `2`     | No       |

## Reservations

| Variable                           | Description                                                                                                                                                                                                                                                             | Default | Required |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `RESERVATION_LONG_LIVED_TTL_HOURS` | Lifetime recorded on a reservation that the ledger holds for a pending transaction (hours). Must be positive and at most `8760`; an invalid value fails the service at boot. Reservations for direct transactions carry a fixed lifetime this variable does not change. | `720`   | No       |

## Readiness and draining

| Variable                                   | Description                                                                                                 | Default | Required |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `READYZ_DRAIN_GRACE_SECONDS`               | Window during which `/readyz` returns 503 after SIGTERM, so Kubernetes de-registers the pod before shutdown | `12`    | No       |
| `READYZ_CACHE_STALENESS_THRESHOLD_SECONDS` | Rule-cache age at which `/readyz` reports `degraded`                                                        | `300`   | No       |

## Reservation gRPC seam

Server side of the seam the Midaz ledger calls to reserve spending limits. Off unless you set `TRACER_GRPC_PORT`.

| Variable                    | Description                                                          | Default     | Required |
| --------------------------- | -------------------------------------------------------------------- | ----------- | -------- |
| `TRACER_GRPC_PORT`          | gRPC listen port for the reservation server                          | unset (off) | No       |
| `TRACER_TLS_MODE`           | Seam security: `mesh` (TLS terminated by the service mesh) or `mtls` | `mesh`      | No       |
| `TRACER_TLS_CERT_FILE`      | Server certificate PEM path (when `mtls`)                            | —           | No       |
| `TRACER_TLS_KEY_FILE`       | Server private-key PEM path (when `mtls`). Sensitive.                | —           | No       |
| `TRACER_TLS_CLIENT_CA_FILE` | Client CA certificate PEM path for mutual verification (when `mtls`) | —           | 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.

* **Access Manager authentication**: `PLUGIN_AUTH_ENABLED`, `PLUGIN_AUTH_ADDRESS`. Enable in production. In discovery-enabled builds (see **Service discovery** below), Tracer resolves the Access Manager host through Consul. It falls back to `PLUGIN_AUTH_ADDRESS` if resolution fails. Current builds always use `PLUGIN_AUTH_ADDRESS`.
* **Multi-tenancy**: `MULTI_TENANT_*`, plus Tracer's per-tenant pool knobs (`MULTI_TENANT_MAX_TENANT_POOLS`, `MULTI_TENANT_MAX_OPEN_CONNS_PER_TENANT`, `TENANT_CAP_RETRY_AFTER_SECONDS`). Off by default. `APPLICATION_NAME` identifies the module to Tenant Manager.
* **Service discovery**: `SD_*` (Consul). Off by default. When `SD_ENABLED=true`, Tracer registers itself as `midaz-tracer` (advertising the HTTP port from `SERVER_ADDRESS`, default `4020`) and resolves Access Manager through Consul. If that resolution fails, it falls back to the static `PLUGIN_AUTH_ADDRESS`. Discovery requires `SD_EXTERNAL_ADDRESS` or `SD_INTERNAL_ADDRESS`. Tracer is the server on the reservation gRPC seam and does not advertise it.
* **Event streaming**: `STREAMING_*` (lib-streaming producer). Off by default.
* **OpenTelemetry**: `ENABLE_TELEMETRY`, `OTEL_*`. Tracer also exposes a Prometheus `/metrics` endpoint.
