> ## 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, 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 — TLS posture, OpenTelemetry, Access Manager authentication, multi-tenancy, service discovery, and event streaming — see the [BYOC configuration reference](/en/reference/byoc-configuration). 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, all origins are allowed — lock to explicit origins in production. The explicit value `*` is rejected at boot when `API_KEY_ENABLED=true`. | — (allow all)    | No                              |
| `TRUSTED_PROXY_CIDRS`             | Trusted proxy CIDRs for `X-Forwarded-For` parsing. Set when running behind a load balancer.                                                                                       | — (uses peer IP) | No                              |

## Database (PostgreSQL)

Tracer stores rules and usage counters in its own `tracer` database on the shared Midaz PostgreSQL primary. Schema migration is applied by a dedicated migration-runner image 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 `TRACER_GRPC_PORT` is set.

| 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 and are documented in full in the [BYOC configuration reference](/en/reference/byoc-configuration). 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 and 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, and temporarily inert: current builds compile the Consul integration out, so `SD_ENABLED=true` has no effect and Tracer always resolves Access Manager from the static `PLUGIN_AUTH_ADDRESS`. In discovery-enabled builds, Tracer registers itself as `midaz-tracer` (advertising the HTTP port from `SERVER_ADDRESS`, default `4020`) and resolves Access Manager through Consul. The reservation gRPC seam is not advertised — Tracer is the server on that seam.
* **Event streaming** — `STREAMING_*` (lib-streaming producer). Off by default.
* **OpenTelemetry** — `ENABLE_TELEMETRY`, `OTEL_*`. Tracer also exposes a Prometheus `/metrics` endpoint.
