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

> Deploy-time environment variables for Lerian BC Correios: runtime posture, datastores, the BC Correio connection, encryption keys, AI, and audit settings.

Lerian BC Correios reads its configuration from the process environment at startup. You set these variables at deploy time. A service restart makes them take effect. [BYOC configuration essentials](/en/reference/byoc-configuration) documents the backbone every Lerian Go service shares.

To install or upgrade Lerian BC Correios, see the [Lerian BC Correios chart README](https://github.com/LerianStudio/helm/tree/main/charts/plugin-bc-correios).

In the tables below, the **Default / Required** column shows the value the service applies when you leave the variable unset. A bold qualifier marks a variable you must set, such as **Required** or **Required outside development**. "Outside development" means an `ENV_NAME` other than `development`. `—` means the service applies no default. A variable flagged `Sensitive.` carries credential or key material. Inject it from your secret manager at deploy time. Never commit a value.

<Note>
  Where a value in the shipped example file differs from the value the code applies, this page publishes the code value.
</Note>

## Service and runtime

| Variable | Default / Required | Description |
| - | - | - |
| `ENV_NAME` | `development` | Deployment environment. Any value other than `development` turns on the stricter startup checks on this page. With `production`, the service refuses `LOG_LEVEL=debug`. |
| `DEPLOYMENT_MODE` | `local` | Operational posture: `local`, `byoc`, or `saas`. In `saas`, every configured dependency must use TLS. Another value stops the boot. |
| `APP_NAME` | `br-correios` | Application name. |
| `LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, or `error`. |
| `SERVER_PORT` | `8080` | HTTP listen port, from 1 to 65535. |
| `SERVER_READ_TIMEOUT_SEC` | `30` | HTTP read timeout, in seconds. |
| `SERVER_WRITE_TIMEOUT_SEC` | `30` | HTTP write timeout, in seconds. |
| `SERVER_SHUTDOWN_TIMEOUT_SEC` | `30` | Time the service waits for open requests at shutdown, in seconds. |
| `DEFAULT_TENANT_ID` | `00000000-0000-0000-0000-000000000001` | Tenant for a token without a tenant claim, in single-tenant mode. Takes a UUID. |
| `STREAMING_CLOUDEVENTS_SOURCE` | `—` | Leave it unset, or set it to exactly `br-correios`. Another value stops the boot. |

## License

| Variable | Default / Required | Description |
| - | - | - |
| `LICENSE_KEY` | **Required** | License credential issued by Lerian. Every environment needs it. `Sensitive.` |
| `ORGANIZATION_IDS` | `global` | Organization scope the license covers. |
| `READYZ_LICENSE_TIMEOUT_SECONDS` | `5` | Time budget of the license check in `/readyz`, in seconds. |

## CORS and proxies

| Variable | Default / Required | Description |
| - | - | - |
| `ALLOWED_ORIGINS` | `*` in development. **Required outside development** | Comma-separated list of allowed browser origins. Outside development, the service refuses `*`. |
| `TRUSTED_PROXIES` | `127.0.0.1,::1` | Comma-separated list of proxy addresses whose `X-Forwarded-For` header the service trusts. |

## PostgreSQL

| Variable | Default / Required | Description |
| - | - | - |
| `POSTGRES_HOST` | `localhost` | Database host. |
| `POSTGRES_PORT` | `5432` | Database port. |
| `POSTGRES_USER` | **Required outside development** | Database user. |
| `POSTGRES_PASSWORD` | `—` | Database password. `Sensitive.` |
| `POSTGRES_NAME` | **Required outside development** | Database name. |
| `POSTGRES_SSLMODE` | `disable` | Database TLS mode. Outside development, the service refuses `disable`. |
| `POSTGRES_MAX_CONNS` | `50` | Maximum connections in the pool. |
| `POSTGRES_MIN_CONNS` | `5` | Minimum connections in the pool. |

## Cache (Valkey)

The cache holds idempotency keys, rate-limit counters, the shared BACEN request quota, and the attachment download budget.

| Variable | Default / Required | Description |
| - | - | - |
| `CACHE_ADDR` | `localhost:6379` | Cache address as `host:port`. |
| `CACHE_PASSWORD` | `—` | Cache password. `Sensitive.` |
| `CACHE_DB` | `0` | Cache logical database number. |
| `CACHE_TLS` | `false` | Uses TLS for the cache connection. |
| `CACHE_CA_CERT` | `—` | Custom CA certificate for the cache TLS connection, as PEM or base64-encoded PEM. Without it, the service uses the system trust store. |
| `CACHE_TTL_SEC` | `60` | Time the service keeps tenant settings in the cache, in seconds. |
| `CACHE_POOL_SIZE` | `10` | Cache connection pool size. |
| `CACHE_MAX_ACTIVE_CONNS` | `20` | Maximum active cache connections. |

## RabbitMQ (audit pipeline)

| Variable | Default / Required | Description |
| - | - | - |
| `RABBITMQ_URL` | `amqp://guest:guest@localhost:5672/` | Broker URL. Outside development, the service refuses the `guest:guest` credentials, and a failed connection stops the boot. `Sensitive.` |

## Encryption and idempotency

| Variable | Default / Required | Description |
| - | - | - |
| `ENCRYPTION_KEY` | **Required outside development** | AES-256-GCM key for the stored BC Correio credentials, AI API keys, and idempotency answers. Exactly 32 bytes. `Sensitive.` |
| `AMQP_SIGNING_KEY` | Derived from `ENCRYPTION_KEY` | Key that signs the audit messages on RabbitMQ. When set, exactly 32 bytes and different from `ENCRYPTION_KEY`. `Sensitive.` |
| `IDEMPOTENCY_TTL_SEC` | `86400` | Time the service keeps an `X-Idempotency` key, in seconds, from 90 to 86400. |

## BC Correio connection

| Variable | Default / Required | Description |
| - | - | - |
| `BC_CORREIO_ENVIRONMENT` | `—` | BACEN environment: `homologation` or `production`. It selects the BC Correio host. |
| `BC_CORREIO_ENDPOINT_URL` | From `BC_CORREIO_ENVIRONMENT` | Full BC Correio endpoint URL. When set, it wins over `BC_CORREIO_ENVIRONMENT`. |
| `BC_CORREIO_TLS_MIN_VERSION` | `TLSv1.2` | Minimum TLS version for BC Correio. |
| `BC_CORREIO_CONNECT_TIMEOUT_SEC` | `30` | Timeout of a call to BC Correio, in seconds, from 1 to 300. |
| `BC_CORREIO_RATE_LIMIT_PER_MINUTE` | `50` | Maximum calls to BC Correio per minute for each Sisbacen credential, from 1 to 60. |
| `BC_CORREIO_RATE_LIMIT_PER_HOUR` | `2700` | Maximum calls to BC Correio per hour for each Sisbacen credential, from 1 to 3000. |
| `BC_CORREIO_RATE_LIMIT_MAX_WAIT_SEC` | `90` | Maximum wait of a call for a free quota slot, in seconds, from 1 to 300. |

## Object storage

| Variable | Default / Required | Description |
| - | - | - |
| `OBJECT_STORAGE_PROVIDER` | `s3` | Attachment storage: `s3` for S3-compatible object storage, or `local` for the local filesystem. |
| `OBJECT_STORAGE_ENDPOINT` | `—` | S3-compatible endpoint URL. |
| `OBJECT_STORAGE_REGION` | `us-east-1` | Storage region. |
| `OBJECT_STORAGE_BUCKET` | `bc-correios-attachments` | Bucket for attachments. |
| `OBJECT_STORAGE_ACCESS_KEY` | `—` | Storage access key. `Sensitive.` |
| `OBJECT_STORAGE_SECRET_KEY` | `—` | Storage secret key. `Sensitive.` |
| `OBJECT_STORAGE_PATH_STYLE` | `false` | Uses path-style S3 addresses. |
| `OBJECT_STORAGE_LOCAL_PATH` | `/data/bc-correios/storage` | Base directory for the `local` provider. |

## Multi-tenancy

| Variable | Default / Required | Description |
| - | - | - |
| `MULTI_TENANT_ENABLED` | `false` | Turns on multi-tenant mode. It needs `PLUGIN_AUTH_ENABLED=true` and an `ENV_NAME` of `staging` or `production`. |
| `MULTI_TENANT_URL` | **Required in multi-tenant mode** | Tenant Manager URL. It must use `https://` unless `MULTI_TENANT_ALLOW_INSECURE_HTTP` is `true`. |
| `MULTI_TENANT_SERVICE_API_KEY` | **Required in multi-tenant mode** | API key for the Tenant Manager. `Sensitive.` |
| `MULTI_TENANT_REDIS_HOST` | **Required in multi-tenant mode** | Host of the Redis that carries tenant events. |
| `MULTI_TENANT_REDIS_PORT` | `6379` | Port of the tenant-event Redis. |
| `MULTI_TENANT_REDIS_PASSWORD` | `—` | Password of the tenant-event Redis. `Sensitive.` |
| `MULTI_TENANT_REDIS_TLS` | `false` | Uses TLS for the tenant-event Redis. |
| `MULTI_TENANT_REDIS_CA_CERT` | `—` | Custom CA certificate for the tenant-event Redis, as PEM or base64-encoded PEM. |
| `MULTI_TENANT_EVENT_CHANNEL` | **Required in multi-tenant mode** | Redis channel for tenant events. |
| `MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD` | `5` | Failures before the Tenant Manager circuit breaker opens. |
| `MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC` | `30` | Time before the Tenant Manager circuit breaker tries again, in seconds. |
| `MULTI_TENANT_MAX_TENANT_POOLS` | `100` | Maximum number of tenant database pools. |
| `MULTI_TENANT_IDLE_TIMEOUT_SEC` | `300` | Idle time before the service closes a tenant pool, in seconds. |
| `MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC` | `30` | Interval between checks of idle tenant connections, in seconds. |
| `MULTI_TENANT_MAX_OPEN_CONNS_PER_TENANT` | `0` | Maximum open connections in each tenant pool. `0` keeps the library default. |
| `MULTI_TENANT_MAX_IDLE_CONNS_PER_TENANT` | `0` | Maximum idle connections in each tenant pool. `0` keeps the library default. |
| `MULTI_TENANT_ALLOW_INSECURE_HTTP` | `false` | Allows `http://` addresses for the Tenant Manager and Access Manager in multi-tenant mode. |
| `STREAMING_OUTBOX_MULTI_TENANT_ENABLED` | `false` | Must be `true` when `MULTI_TENANT_ENABLED` is `true`, or the service does not start. |

## AI

| Variable | Default / Required | Description |
| - | - | - |
| `FEATURE_AI_INSIGHTS_ENABLED` | `true` | Turns AI analysis of mail on or off. |
| `AI_DEFAULT_MODEL_OPENAI` | `gpt-4o-mini` | Model for a tenant that uses `openai` and sets no model. |
| `AI_DEFAULT_MODEL_ANTHROPIC` | `claude-sonnet-4-20250514` | Model for a tenant that uses `anthropic` and sets no model. |
| `AI_DEFAULT_MODEL_GEMINI` | `gemini-2.0-flash` | Model for a tenant that uses `gemini` and sets no model. |
| `AI_DEFAULT_SYSTEM_PROMPT` | Built-in prompt | Default system prompt for the AI analysis. |
| `AI_TENANT_RATE_LIMIT_PER_MIN` | `50` | Maximum AI calls per minute for each tenant. |
| `AI_CIRCUIT_BREAKER_THRESHOLD` | `5` | Failures in a row before the AI circuit breaker of a tenant and provider opens. |
| `AI_CIRCUIT_BREAKER_HALF_OPEN_SEC` | `30` | Time before an open AI circuit breaker tries one call again, in seconds. |
| `AI_TENANT_MAX_CONCURRENT` | `3` | Maximum concurrent AI calls for each tenant. |
| `AI_GLOBAL_MAX_CONCURRENT` | `15` | Maximum concurrent AI calls for the whole instance. |
| `AI_ACQUIRE_TIMEOUT_SEC` | `30` | Maximum wait of a background AI call for a free slot, in seconds. |
| `AI_HTTP_ACQUIRE_TIMEOUT_SEC` | `5` | Maximum wait of a reanalyze request for a free slot, in seconds. After it, the request answers `202`. |
| `AI_INLINE_PROVIDER_TIMEOUT_SEC` | `15` | Timeout of one AI call during the polling cycle, in seconds. |
| `AI_BODY_INLINE_THRESHOLD` | `200` | Minimum body length, in characters, for an analysis during the polling cycle. |

## Transmission

| Variable | Default / Required | Description |
| - | - | - |
| `TRANSMISSION_PENDING_GRACE_SEC` | `30` | Grace window for a `PENDING` send, in seconds, from 5 to 300. When a repeat finds a `PENDING` send older than this, the send becomes `AMBIGUOUS`. |
| `TRANSMISSION_RETRY_MAX_ATTEMPTS` | `3` | Attempts to record a send that BC Correio accepted, from 1 to 10. |
| `TRANSMISSION_METRICS_QUERY_TIMEOUT_SEC` | `2` | Time budget of the database query behind the pending-send metric, in seconds, from 1 to 8. |

## Audit

| Variable | Default / Required | Description |
| - | - | - |
| `FEATURE_AUDIT_ENABLED` | `true` | Turns the audit pipeline on or off. Outside development, the service refuses `false`. |
| `AUDIT_OUTBOX_POLL_INTERVAL_SEC` | `2` | Interval between audit outbox reads, in seconds, from 1 to 300. |
| `AUDIT_OUTBOX_BATCH_LIMIT` | `50` | Maximum audit events in one read for each tenant, from 1 to 1000. |
| `AUDIT_OUTBOX_MAX_ATTEMPTS` | `50` | Attempts to publish one audit event, from 1 to 1000. |
| `AUDIT_OUTBOX_RETENTION_DAYS` | `7` | Days before the service deletes a published outbox row, from 1 to 90. |

## Authentication

| Variable | Default / Required | Description |
| - | - | - |
| `PLUGIN_AUTH_ENABLED` | **Required** | `true` or `false`. A blank value stops the boot. `false` needs an `ENV_NAME` of `development`, `develop`, `dev`, `local`, or `test`, and never works with `DEPLOYMENT_MODE=saas`. With `false`, requests still need a bearer token. |
| `PLUGIN_AUTH_ADDRESS` | **Required when `PLUGIN_AUTH_ENABLED` is `true`** | Lerian Access Manager address. In multi-tenant mode, it must use `https://` unless `MULTI_TENANT_ALLOW_INSECURE_HTTP` is `true`. |

## Telemetry and metrics

| Variable | Default / Required | Description |
| - | - | - |
| `TRACING_ENABLED` | `false` | Exports traces over OTLP. |
| `METRICS_ENABLED` | `false` | Exports metrics over OTLP. |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `—` | OTLP collector endpoint. |
| `OTEL_SERVICE_NAME` | `br-correios` | Service name in telemetry. |
| `OTEL_LIBRARY_NAME` | `br-correios` | Instrumentation library name in telemetry. |
| `OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT` | Value of `ENV_NAME` | Deployment environment in telemetry. |
| `METRICS_PROMETHEUS_ENABLED` | `false` | Opens a separate listener for a Prometheus scrape. |
| `METRICS_PROMETHEUS_ADDRESS` | `127.0.0.1:9076` | Address of the Prometheus listener. |

## Rate limits

| Variable | Default / Required | Description |
| - | - | - |
| `RATE_LIMIT_ENABLED` | `false` | Turns on the request budgets per tenant and operation. |
| `RATE_LIMIT_REDIS_TIMEOUT_MS` | `500` | Timeout of a rate-limit counter call to the cache, in milliseconds. |
| `ATTACHMENT_BANDWIDTH_BUDGET_MB_PER_MIN` | `500` | Attachment download budget per tenant, in megabytes per minute, from 1 to 102400. |


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