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

# JD Courier environment variables

> Environment variables that JD Courier reads at startup: roles, server, PostgreSQL, Access Manager, JD SPB channel, SOAP interface, Pix transit, SPB drain, license, multi-tenancy and telemetry.

JD Courier reads these variables when the process starts. A change takes effect after you restart the process. Each process reads the variables of the roles in `COURIER_ROLES`.

In the tables, **Required** marks a variable that you must set, always or under the condition named. `—` means no default. 🔒 marks a secret: keep it in your secret vault.

> [!NOTE]
>
> With `ENVIRONMENT_NAME=production`, the Courier does not start unless all of these are true: `PLUGIN_AUTH_ENABLED` is `true`, `POSTGRES_PASSWORD` is set, `POSTGRES_SSLMODE` is not `disable`, and `ALLOW_CORS_WILDCARD` is not `true`. Each role adds its own checks, named in the tables below.

## Service and server

| Variable | Description | Default | Required |
| - | - | - | - |
| `COURIER_ROLES` | The roles of the process, separated by commas: `spb-consumer`, `spb-sender`, `pix-ingress`, `admin`. An unknown or repeated role stops the boot. `spb-consumer` runs alone in its process. | — | Yes |
| `ENVIRONMENT_NAME` | The environment. `production` turns on the production checks. `ENV_NAME` is read when `ENVIRONMENT_NAME` is not set. | `development` | No |
| `DEPLOYMENT_MODE` | `byoc`, `saas`, or `local`. Another value stops the boot. | `local` | No |
| `LOG_LEVEL` | The log level. | `info` | No |
| `SERVER_ADDRESS` | The HTTP port: the probes, the operator API, the engine API, and the Pix address. | `:8080` | No |
| `SERVER_TLS_CERT_FILE`, `SERVER_TLS_KEY_FILE` | The certificate and key for TLS on the HTTP port. Set both or neither. A process with `spb-sender` or with the Pix transit refuses them unless `TLS_TERMINATED_UPSTREAM` is `true`. | — | No |
| `TLS_TERMINATED_UPSTREAM` | `true` when TLS ends before the HTTP port. | `false` | No |
| `HTTP_BODY_LIMIT_BYTES` | The largest request body on the HTTP port, in bytes. | `1048576` | No |
| `SWAGGER_ENABLED` | Serve the OpenAPI document at the root of the HTTP port. The Courier ignores it in production. | `false` | No |
| `SYSTEMPLANE_ENABLED` | Turn on the runtime settings and their API under `/system`. | `false` | No |
| `INFRA_CONNECT_TIMEOUT_SEC` | The time limit to connect to the datastores at boot, in seconds. | `30` | No |
| `IDEMPOTENCY_RETRY_WINDOW_SEC` | How long the Courier keeps the answer to an `X-Idempotency` key, in seconds. | `300` | No |
| `ALLOW_CORS_WILDCARD` | Production refuses `true`. | — | No |

## PostgreSQL

| Variable | Description | Default | Required |
| - | - | - | - |
| `POSTGRES_HOST` | The primary host. | `localhost` | No |
| `POSTGRES_PORT` | The primary port. | `5432` | No |
| `POSTGRES_USER` | The database user. | `jd-courier` | No |
| `POSTGRES_PASSWORD` | 🔒 The database password. | — | In production |
| `POSTGRES_NAME` | The database name. | `jd-courier` | No |
| `POSTGRES_SSLMODE` | The libpq TLS mode. With `disable`, the Courier does not start unless `ALLOW_INSECURE_TLS` is `true`. Production refuses `disable`. Use `verify-full` in production. | `require` | No |
| `POSTGRES_REPLICA_HOST`, `POSTGRES_REPLICA_PORT`, `POSTGRES_REPLICA_USER`, `POSTGRES_REPLICA_PASSWORD`, `POSTGRES_REPLICA_NAME`, `POSTGRES_REPLICA_SSLMODE` | An optional read replica. A value that you do not set takes the value of the primary. When you set any of them, `POSTGRES_REPLICA_HOST` is required. Production refuses `POSTGRES_REPLICA_SSLMODE=disable`. | — | No |
| `POSTGRES_MAX_OPEN_CONNS` | The largest number of open connections. | `25` | No |
| `POSTGRES_MAX_IDLE_CONNS` | The largest number of idle connections. | `5` | No |
| `POSTGRES_CONN_MAX_LIFETIME_MINS` | The longest life of a connection, in minutes. | `30` | No |
| `POSTGRES_CONN_MAX_IDLE_TIME_MINS` | The longest idle time of a connection, in minutes. | `5` | No |
| `POSTGRES_CONNECT_TIMEOUT_SEC` | The time limit to open a connection, in seconds. | `10` | No |
| `ALLOW_INSECURE_TLS` | `true` lets the datastore connections work without TLS. | `false` | No |

## Access Manager

| Variable | Description | Default | Required |
| - | - | - | - |
| `PLUGIN_AUTH_ENABLED` | Check the Access Manager token and permission on each call. `false` needs `ALLOW_AUTH_DISABLED_LOCAL_ONLY=true`. Production and multi-tenant mode refuse `false`. | `true` | No |
| `PLUGIN_AUTH_HOST` | The address of your Access Manager. | — | When `PLUGIN_AUTH_ENABLED` is `true` |
| `ALLOW_AUTH_DISABLED_LOCAL_ONLY` | Lets `PLUGIN_AUTH_ENABLED=false` start, on a developer's machine only. | `false` | No |
| `AUTH_M2M_INVERSION_ENABLED` | Binds each engine call to the identity that Access Manager verified. With `false`, the Courier refuses every engine credential with `401`, and a production process with the `admin` role does not start. | `true` | No |
| `AUTH_M2M_PRODUCT_FORWARD_ENABLED` | Sends the product name of the Courier to Access Manager when it authorizes an engine call. | `true` | No |
| `AUTH_TIMEOUT`, `AUTH_CACHE_TTL`, `AUTH_RETRY_MAX`, `AUTH_BREAKER_ENABLED`, `AUTH_REQUIRED`, `AUTH_PRINCIPAL_REQUIRED_WHEN_DISABLED`, `AUTH_JWT_VERIFY_CERT`, `AUTH_JWT_VERIFY_CERT_PATH`, `AUTH_JWT_ISSUER` | The settings of the Access Manager client. A value that is not valid stops the boot. | The client defaults | No |
| `IDP_DECLARATION_ENABLED` | In single-tenant mode, `true` publishes the permissions of the Courier and its partner opt-in to your Access Manager. Unset or `false` publishes only the partner opt-in. | — | No |
| `IDP_HOST` | The address of the Access Manager identity service, where the Courier publishes them. | — | For the publication |
| `IDP_M2M_CLIENT_ID` | The client ID of the application that publishes them. | — | For the publication |
| `IDP_M2M_CLIENT_SECRET` | 🔒 The secret of that application. | — | For the publication |

See [Access Manager](https://docs.lerian.studio/en/interfaces/jd-courier/jd-courier-deployment.md#access-manager) for what the publication does.

## JD SPB channel

The `spb-consumer` and `spb-sender` roles read these variables.

| Variable | Description | Default | Required |
| - | - | - | - |
| `JD_BASE_URL` | The address of the JD SPB service. Use https in production. | — | In production, in single-tenant mode |
| `JD_SOAP_PATH` | The path of the JD SOAP service. | `/soap` | No |
| `JD_LEGACY_CODE` | The JD credential that you already hold. At most 10 bytes. | — | In production, in single-tenant mode |
| `JD_USER_CODE` | The JD credential that you already hold. At most 10 bytes. | — | In production, in single-tenant mode |
| `JD_PASSWORD` | 🔒 The JD credential that you already hold. At most 20 bytes. | — | In production, in single-tenant mode |
| `SPB_VENDOR_TIMEOUT` | How long the Courier waits for JD. It must be more than zero and less than `8s`. | `7s` | No |
| `JD_ALLOW_PRIVATE_NETWORK` | `true` lets the Courier connect to JD at a private network address, for the SPB channel and the SPI cabin. Production accepts it. | `false` | No |
| `JD_PRIVATE_KEY_PEM` | Must not be present in production. The Courier signs nothing. | — | No |

## SOAP interface

The `spb-sender` role reads these variables.

| Variable | Description | Default | Required |
| - | - | - | - |
| `SOAP_SERVER_ADDRESS` | The SOAP port. | `:8081` | No |
| `SOAP_MAX_BODY_BYTES` | The largest SOAP request body, in bytes. | `10485760` | No |
| `SOAP_TLS_CERT_FILE`, `SOAP_TLS_KEY_FILE` | The certificate and key for TLS on the SOAP port. Set both or neither. The minimum TLS version is 1.2. | — | In production, unless `SOAP_TLS_TERMINATED_UPSTREAM` is `true` |
| `SOAP_TLS_TERMINATED_UPSTREAM` | `true` when TLS ends before the SOAP port. | `false` | No |
| `SPB_CHANNEL_CREDENTIAL_ROTATION_OVERLAP` | How long the earlier SOAP and Pix transit credentials of an engine keep working after the operator issues a new one. The `admin` role reads it when it issues a credential. `spb-sender` refuses a value that is not positive. | `24h` | No |

## Pix transit

The `admin` role reads these variables.

| Variable | Description | Default | Required |
| - | - | - | - |
| `PIX_TRANSIT_SERVER_ADDRESS` | The address of the Pix transit. When it is empty, the Courier serves no transit. | — | For the transit |
| `PIX_TRANSIT_TLS_CERT_FILE`, `PIX_TRANSIT_TLS_KEY_FILE` | The certificate and key for TLS on the transit. Set both or neither. The minimum TLS version is 1.2. | — | In production, unless `PIX_TRANSIT_TLS_TERMINATED_UPSTREAM` is `true` |
| `PIX_TRANSIT_TLS_TERMINATED_UPSTREAM` | `true` when TLS ends before the transit. | `false` | No |
| `JD_SPI_BASE_URL` | In single-tenant mode, the address of the SPI cabin of JD. Use https in production. | — | For the transit |
| `JD_SPI_CLIENT_ID` | In single-tenant mode, the client ID of the SPI cabin credential of your institution. | — | For the transit |
| `JD_SPI_CLIENT_SECRET` | 🔒 In single-tenant mode, the secret of that credential. | — | For the transit |
| `JD_SPI_USE_SERVICE_SEGMENTS` | `true` when JD serves the SPI cabin through its gateway paths: the Courier then requests its token under `/auth` and sends account validation results under `/spi-api`. | `false` | No |

## SPB drain

The `spb-consumer` role reads these variables. `SPB_TAKE_BUDGET_SEC` plus the longer of `SPB_IDLE_INTERVAL_SEC` and `SPB_EMPTY_BACKOFF_CAP_SEC` must stay under `SPB_LEASE_TTL_SEC`.

| Variable | Description | Default | Required |
| - | - | - | - |
| `POD_NAME` | The holder name of the read lease. When it is empty, the Courier uses the host name. | — | No |
| `SPB_LEASE_TTL_SEC` | How long the read lease lasts without a renewal, in seconds. | `30` | No |
| `SPB_TAKE_BUDGET_SEC` | The longest time to take one message from JD, in seconds. It must be at least `SPB_VENDOR_TIMEOUT`. | `15` | No |
| `SPB_IDLE_INTERVAL_SEC` | The wait while the drain does not read, in seconds. | `5` | No |
| `SPB_EMPTY_BACKOFF_CAP_SEC` | The longest wait after JD reports an empty queue, in seconds. | `10` | No |
| `SPB_PERSIST_TIMEOUT_SEC` | The time limit of one attempt to store a message, in seconds. | `60` | No |
| `SPB_TENANT_REFRESH_SEC` | How often the drain reads the list of tenants again, in seconds. | `30` | No |
| `SPB_MESSAGE_SIZE_ALERT_BYTES` | A message larger than this writes a warning. The Courier stores it. | `1048576` | No |

## Pix and engine credentials

| Variable | Description | Default | Required |
| - | - | - | - |
| `AWS_REGION` | The AWS region of AWS Secrets Manager, where the Courier reads the credentials that it uses at the engines. | `us-east-1` | No |

See [Engine credentials](https://docs.lerian.studio/en/interfaces/jd-courier/jd-courier-deployment.md#engine-credentials).

## License

| Variable | Description | Default | Required |
| - | - | - | - |
| `LICENSE_KEY` | 🔒 Your Lerian license key. | — | Yes |
| `ORGANIZATION_IDS` | Your organization ID. | — | No |
| `APPLICATION_NAME` | The product name that the license check uses. Leave it unset: the Courier then uses its own product name. | — | No |

## Multi-tenancy

| Variable | Description | Default | Required |
| - | - | - | - |
| `MULTI_TENANT_ENABLED` | Turn on multi-tenant mode. | `false` | No |
| `MULTI_TENANT_URL` | The address of the Tenant Manager. | — | In multi-tenant mode |
| `MULTI_TENANT_SERVICE_API_KEY` | 🔒 The key of the Courier at the Tenant Manager. | — | In multi-tenant mode |
| `MULTI_TENANT_REDIS_HOST` | The Redis host of the tenant cache. | — | In multi-tenant mode |
| `MULTI_TENANT_REDIS_PORT` | The Redis port. | `6379` | No |
| `MULTI_TENANT_REDIS_PASSWORD` | 🔒 The Redis password. | — | No |
| `MULTI_TENANT_REDIS_TLS` | Connect to Redis with TLS. | `false` | No |
| `MULTI_TENANT_MAX_TENANT_POOLS` | The largest number of tenant connection pools. | `100` | No |
| `MULTI_TENANT_IDLE_TIMEOUT_SEC` | How long an idle tenant pool stays open, in seconds. | `300` | No |
| `MULTI_TENANT_TIMEOUT` | The time limit of a call to the Tenant Manager, in seconds. | `30` | No |
| `MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD` | The failures that open the circuit breaker of the Tenant Manager. | `5` | No |
| `MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC` | How long the circuit breaker stays open, in seconds. | `30` | No |
| `MULTI_TENANT_CACHE_TTL_SEC` | How long the Courier keeps a tenant configuration, in seconds. | `120` | No |
| `MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC` | How often the Courier checks the tenant connections, in seconds. | `30` | No |

## Telemetry

| Variable | Description | Default | Required |
| - | - | - | - |
| `ENABLE_TELEMETRY` | Turn on OpenTelemetry. | `true` | No |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | The OTLP collector address. | `localhost:4317` | No |
| `OTEL_RESOURCE_SERVICE_NAME` | The service name on the telemetry. | `jd-courier` | No |
| `OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT` | The environment name on the telemetry. | `development` | No |
| `OTEL_LIBRARY_NAME` | The instrumentation library name on the telemetry. | The Courier module name | No |
| `OTEL_TRUST_INBOUND_TRACE_CONTEXT` | Continue the trace that a caller sends. Set `true` only behind a gateway that you trust. | `false` | No |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.