Configuration reference
EHRbase-rs is configured entirely through EHRBASE_* environment variables,
optionally backed by TOML files for values that do not fit cleanly in env (a
Basic-auth user store, a full OIDC block, ABAC policies, and so on). This
chapter is the complete reference: how configuration loads, the two naming
conventions you must know, and a table per area listing every key with its
type, default, and meaning. Everything here is drawn from the server’s own
configuration code.
- How configuration loads
- Server (REST)
- Authentication
- Authorization (RBAC + ABAC)
- Database
- Telemetry and logging
- Management surface
- Version signing
- System log (ATNA auditing)
- Change events (AMQP outbox)
- FHIR outbound emitter
- S3 multimedia externalization
- External terminology validation
- Process / CLI
- What belongs in a mounted file
How configuration loads
There is no single global configuration object. The server is composed of independent modules, each of which loads its own settings from three layers, in increasing precedence:
- Built-in defaults (the values in the tables below),
- an optional TOML file for that module (pointed at by an
EHRBASE_<AREA>_CONFIGvariable), then EHRBASE_<AREA>_-prefixed environment variables, which win.
The development Compose stack, for example, points EHRBASE_REST_CONFIG at
docker/ehrbase.dev.toml to supply the Basic-auth user store (which env cannot
carry as a list), while everything else stays on defaults or env overrides.
Warning
Two naming conventions. Most modules use a double underscore (
__) to separate nested fields —EHRBASE_REST_AUTH__ENABLEDmaps toauth.enabled. There are two exceptions:
- Telemetry is flat:
EHRBASE_OTEL_*andEHRBASE_LOG_*have no nesting.- Management uses a single underscore for its one nested group:
EHRBASE_MANAGEMENT_ENDPOINTS_HEALTH, not__.Getting the separator wrong is the most common configuration mistake.
Enum values are case-sensitive on the wire. Where a column lists
enum{a,b,c}, use exactly those lowercase (or snake_case) tokens. Secret
values (EHRBASE_SIGNING_KEY_PASSPHRASE, EHRBASE_REST_AUTH__OIDC__HMAC_SECRET,
Basic-auth password hashes) are redacted from the management /env endpoint and
from logs.
Server (REST)
Prefix EHRBASE_REST_, separator __, optional file EHRBASE_REST_CONFIG.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_REST_CONFIG | path | none | Path to the REST TOML config file (loaded before env). |
EHRBASE_REST_BIND | socket address | 0.0.0.0:8080 | Address the API listener binds. |
EHRBASE_REST_BASE_PATH | string | /ehrbase/rest/openehr/v1 | Base path all API routes hang off. |
EHRBASE_REST_SWAGGER_UI | boolean | true | Serve Swagger UI + the OpenAPI JSON. Consider off in production. |
EHRBASE_REST_CORS_PERMISSIVE | boolean | false | Enable a permissive (development) CORS policy. |
EHRBASE_REST_ADMIN__ENABLED | boolean | false | Mount the ADMIN API group (routes 404 when off). |
EHRBASE_REST_TERMINOLOGY__ENABLED | boolean | false | Mount the terminology extension API group. |
EHRBASE_REST_EVENT_SUBSCRIPTION__ENABLED | boolean | false | Mount the event-subscription admin extension API. |
EHRBASE_REST_FHIR__ENABLED | boolean | false | Mount the FHIR R4 inbound/façade routes. |
EHRBASE_REST_TENANCY__ENABLED | boolean | false | Activate multi-tenancy (tenant middleware + row-level scoping). |
EHRBASE_REST_TENANCY__CLAIM | string | tenant | JWT-claim path carrying the tenant key. |
EHRBASE_REST_TENANCY__HEADER | string | none | Dev-only request-header tenant override. Leave unset in production — a client header must not select a tenant. |
Authentication
Nested under EHRBASE_REST_AUTH__ (part of the REST config). The Basic-auth
user store is a list and is realistically supplied via the mounted TOML file;
the env forms are shown for completeness.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_REST_AUTH__ENABLED | boolean | true | Master auth switch. false = all requests pass unauthenticated (development only). |
EHRBASE_REST_AUTH__ADMIN_SCOPE | string | none | Deprecated back-compat scope→role alias; still consulted by the management admin gate. |
EHRBASE_REST_AUTH__BASIC__USERS | list of {username, password_hash, roles} | none (Basic off) | Basic-auth user store. Passwords are Argon2 PHC hashes; per-user roles default to ["USER"]. Set via TOML. |
EHRBASE_REST_AUTH__OIDC__ISSUER | URL | none (bearer off) | Expected token issuer (iss); also the OIDC discovery base. |
EHRBASE_REST_AUTH__OIDC__AUDIENCES | list | [] (not checked) | Accepted aud values. |
EHRBASE_REST_AUTH__OIDC__ALGORITHMS | list | ["RS256"] | Accepted JWT signature algorithms. |
EHRBASE_REST_AUTH__OIDC__HMAC_SECRET | string (secret) | none | Symmetric HS256 secret (development/test). Prefer JWKS/discovery in production. |
EHRBASE_REST_AUTH__OIDC__JWKS_JSON | string (JSON) | none | Static JWKS document; preferred over discovery when present. |
Authorization (RBAC + ABAC)
Prefix EHRBASE_AUTHZ_, separator __, optional file EHRBASE_AUTHZ_CONFIG.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_AUTHZ_CONFIG | path | none | Path to the authz TOML config file. |
EHRBASE_AUTHZ_RBAC__ENABLED | boolean | true | Coarse role gate (active only when auth is enabled). |
EHRBASE_AUTHZ_RBAC__ADMIN_ROLE | string | ADMIN | Role required for admin-class operations. |
EHRBASE_AUTHZ_RBAC__USER_ROLE | string | USER | Baseline clinical role. |
EHRBASE_AUTHZ_RBAC__ROLE_CLAIMS | list | ["realm_access.roles","scope"] | JWT claim paths mined for roles. |
EHRBASE_AUTHZ_RBAC__MANAGEMENT_ACCESS | enum{admin_only,private,public} | admin_only | Access level for the management surface. |
EHRBASE_AUTHZ_ABAC__ENABLED | boolean | false | Master ABAC (attribute-based) switch. |
EHRBASE_AUTHZ_ABAC__ENGINE | enum{cedar,remote} | cedar | Policy engine: embedded Cedar or a remote decision point. |
EHRBASE_AUTHZ_ABAC__ORGANIZATION_CLAIM | string | organization_id | JWT claim carrying the caller’s organization. |
EHRBASE_AUTHZ_ABAC__PATIENT_CLAIM | string | patient_id | JWT claim carrying the patient id (blank disables the subject gate). |
EHRBASE_AUTHZ_ABAC__CEDAR__POLICY_DIR | path | none | Directory of *.cedar policy files (required for the cedar engine). |
EHRBASE_AUTHZ_ABAC__CEDAR__RELOAD_SECS | integer | none | Optional Cedar hot-reload interval (seconds). |
EHRBASE_AUTHZ_ABAC__REMOTE__SERVER | URL | none | Remote decision-point base URL (required for the remote engine). |
EHRBASE_AUTHZ_ABAC__REMOTE__CONNECT_TIMEOUT_MS | integer (ms) | 2000 | Remote-PDP connect timeout. |
EHRBASE_AUTHZ_ABAC__REMOTE__REQUEST_TIMEOUT_MS | integer (ms) | 5000 | Remote-PDP request timeout. |
Database
Prefix EHRBASE_DB_, no nesting, environment-only (no config file).
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_DB_URL | URL | none (required) | PostgreSQL connection URL, postgres://user:pass@host:port/db. DATABASE_URL is accepted as a fallback. |
EHRBASE_DB_MAX_CONNECTIONS | integer | 10 | Upper bound of the connection pool. |
EHRBASE_DB_MIN_CONNECTIONS | integer | 0 | Idle connections the pool keeps open. |
EHRBASE_DB_ACQUIRE_TIMEOUT_SECS | integer (s) | 30 | Wait for a free connection before failing. |
Note
EHRBASE_DB_NAME,EHRBASE_DB_USER, andEHRBASE_DB_PASSWORDare not read by the server — they configure the PostgreSQL init image. The server takes a singleEHRBASE_DB_URL.
Telemetry and logging
Prefixes EHRBASE_OTEL_ and EHRBASE_LOG_. Flat (no __ nesting),
environment-only.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_OTEL_OTLP_ENDPOINT | URL | none | OTLP/gRPC collector endpoint. Unset = the OTel layer is not installed (zero overhead). |
EHRBASE_OTEL_SERVICE_NAME | string | ehrbase | service.name resource attribute. |
EHRBASE_OTEL_ENVIRONMENT | string | dev | deployment.environment resource attribute. |
EHRBASE_OTEL_TRACES_SAMPLE_RATIO | float | 1.0 | Head-sampling ratio. |
EHRBASE_OTEL_METRICS_PUSH | boolean | false | Also push metrics over OTLP (alongside Prometheus pull). |
EHRBASE_LOG_FORMAT | enum{auto,json,pretty} | auto | Log rendering. json for cluster log collectors; auto picks JSON when stdout is not a TTY. |
EHRBASE_LOG_FILTER | string | info,ehrbase=info | Log-filter directives (RUST_LOG is the fallback when unset). |
Management surface
Prefix EHRBASE_MANAGEMENT_, single-underscore nesting for endpoints,
optional file EHRBASE_MANAGEMENT_CONFIG. Off in the bare binary; the Helm
chart turns it on for probes.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_MANAGEMENT_CONFIG | path | none | Path to the management TOML config file. |
EHRBASE_MANAGEMENT_ENABLED | boolean | false | Master switch; off = no management routes mounted. |
EHRBASE_MANAGEMENT_BASE_PATH | string | /management | Base path for the management endpoints. |
EHRBASE_MANAGEMENT_PORT | integer (u16) | none | Serve management on its own listener/port instead of the main API listener. |
EHRBASE_MANAGEMENT_ACCESS_DEFAULT | enum{off,admin_only,private,public} | admin_only | Global default access level (a per-endpoint level wins). |
EHRBASE_MANAGEMENT_PROBES_ENABLED | boolean | false | Mount the public /health/liveness + /health/readiness probes. |
EHRBASE_MANAGEMENT_ENDPOINTS_HEALTH | enum{off,admin_only,private,public} | off | Access level of /management/health. |
EHRBASE_MANAGEMENT_ENDPOINTS_INFO | enum{off,admin_only,private,public} | off | Access level of /management/info. |
EHRBASE_MANAGEMENT_ENDPOINTS_METRICS | enum{off,admin_only,private,public} | off | Access level of /management/metrics. |
EHRBASE_MANAGEMENT_ENDPOINTS_PROMETHEUS | enum{off,admin_only,private,public} | off | Access level of /management/prometheus. |
EHRBASE_MANAGEMENT_ENDPOINTS_ENV | enum{off,admin_only,private,public} | off | Access level of /management/env (redacted config). |
EHRBASE_MANAGEMENT_ENDPOINTS_LOGGERS | enum{off,admin_only,private,public} | off | Access level of /management/loggers (runtime log control). |
Version signing
Prefix EHRBASE_SIGNING_, separator __, optional file
EHRBASE_SIGNING_CONFIG. On by default in digest mode.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_SIGNING_CONFIG | path | none | Path to the signing TOML config file. |
EHRBASE_SIGNING_ENABLED | boolean | true | Server-side signing of committed versions. |
EHRBASE_SIGNING_MODE | enum{digest,pgp} | digest | SHA-256 integrity digest, or an OpenPGP detached signature. |
EHRBASE_SIGNING_KEY_PATH | path | none | Armored RFC 4880 secret key (required for pgp). |
EHRBASE_SIGNING_KEY_PASSPHRASE | string (secret) | none | Key passphrase (kept in memory, never serialized). |
EHRBASE_SIGNING_VERIFY_ON_READ | enum{off,warn,strict} | off | Read-time recompute-and-compare policy. |
Warning
pgpmode fails closed at boot if the key is missing or unusable — the server will not start. Verify the key and passphrase before switching modes.
System log (ATNA auditing)
Prefix EHRBASE_ATNA_, separator __, optional file EHRBASE_ATNA_CONFIG.
Off by default.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_ATNA_CONFIG | path | none | Path to the ATNA TOML config file. |
EHRBASE_ATNA_ENABLED | boolean | false | Master ATNA audit switch. |
EHRBASE_ATNA_ENTERPRISE_SITE_ID | string | none | Enterprise/site id (AuditEnterpriseSiteID). |
EHRBASE_ATNA_REPOSITORY_HOST | string | localhost | Audit Record Repository (ARR) host. |
EHRBASE_ATNA_REPOSITORY_PORT | integer (u16) | 514 | ARR port (514 UDP / 6514 TLS typical). |
EHRBASE_ATNA_TRANSPORT | enum{udp,tls} | udp | Syslog transport to the ARR. Use tls for PHI-adjacent audit. |
EHRBASE_ATNA_SOURCE_ID | string | ehrbase | Audit source id. |
EHRBASE_ATNA_VALUE_IF_MISSING | string | UNKNOWN | Fill value for empty mandatory fields. |
EHRBASE_ATNA_SUPPRESS_LOGIN_EVENTS | boolean | true | Skip auth/login activity events. |
EHRBASE_ATNA_FAIL_MODE | enum{open,closed} | open | On undeliverable audit: succeed and meter (open) or reject with 503 (closed). |
EHRBASE_ATNA_RESOLVE_SUBJECT | boolean | false | Enrich the patient participant via a subject lookup. |
EHRBASE_ATNA_QUEUE_CAPACITY | integer | 1024 | Bounded audit queue capacity. |
EHRBASE_ATNA_SERVER_HOST | string | none | This node’s advertised address (NetworkAccessPointID). |
EHRBASE_ATNA_TLS_CA_PATH | path | none | PEM CA file to trust for TLS transport. |
EHRBASE_ATNA_TLS_IDENTITY_CERT_PATH | path | none | Client-certificate PEM for mutual TLS. |
EHRBASE_ATNA_TLS_IDENTITY_KEY_PATH | path | none | Client-key PEM for mutual TLS. |
Change events (AMQP outbox)
Prefix EHRBASE_EVENTS_, separator __, optional file EHRBASE_EVENTS_CONFIG.
Off by default. Envelopes are PHI-free by design.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_EVENTS_CONFIG | path | none | Path to the events TOML config file. |
EHRBASE_EVENTS_ENABLED | boolean | false | Spawn the outbox publisher. |
EHRBASE_EVENTS_URL | AMQP URL | amqp://guest:guest@localhost:5672/%2f | RabbitMQ broker URL. |
EHRBASE_EVENTS_EXCHANGE | string | ehrbase.events | Topic exchange for PHI-free event envelopes. |
EHRBASE_EVENTS_TLS | boolean | false | Upgrade an amqp:// URL to amqps://. |
EHRBASE_EVENTS_BATCH_SIZE | integer | 128 | Outbox rows drained per poll. |
EHRBASE_EVENTS_POLL_INTERVAL_MS | integer (ms) | 1000 | Poll interval when the outbox is idle. |
EHRBASE_EVENTS_RETENTION_DAYS | integer (days) | 7 | Published-row retention window. |
EHRBASE_EVENTS_PRUNE_INTERVAL_SECS | integer (s) | 3600 | Retention-prune cadence. |
EHRBASE_EVENTS_PUBLISH_MAX_RETRIES | integer | 3 | Per-row publish retries before backing off. |
FHIR outbound emitter
Prefix EHRBASE_FHIR_OUTBOUND_, separator __, optional file
EHRBASE_FHIR_OUTBOUND_CONFIG. Off by default.
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_FHIR_OUTBOUND_CONFIG | path | none | Path to the FHIR-outbound TOML config file. |
EHRBASE_FHIR_OUTBOUND_ENABLED | boolean | false | Enable the FHIR resource emitter. |
EHRBASE_FHIR_OUTBOUND_URL | AMQP URL | amqp://guest:guest@localhost:5672/%2f | Broker URL. |
EHRBASE_FHIR_OUTBOUND_EXCHANGE | string | ehrbase.fhir | Topic exchange (separate from events, for PHI isolation). |
EHRBASE_FHIR_OUTBOUND_TLS | boolean | false | Upgrade an amqp:// URL to amqps://. |
EHRBASE_FHIR_OUTBOUND_BATCH_SIZE | integer | 128 | Outbox rows scanned per poll. |
EHRBASE_FHIR_OUTBOUND_POLL_INTERVAL_MS | integer (ms) | 1000 | Poll interval when idle. |
EHRBASE_FHIR_OUTBOUND_PUBLISH_MAX_RETRIES | integer | 3 | Per-message publish retries before backing off. |
Warning
This stream carries PHI — the mapped FHIR resource. It is a deliberately separate switch and exchange from the PHI-free change-event stream so broker access control can isolate it. Enable it only against a TLS, access-controlled broker.
S3 multimedia externalization
Prefix EHRBASE_MULTIMEDIA_, separator __, optional file
EHRBASE_MULTIMEDIA_CONFIG. Off by default (blobs stay inline, byte-identical).
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_MULTIMEDIA_CONFIG | path | none | Path to the multimedia TOML config file. |
EHRBASE_MULTIMEDIA_ENABLED | boolean | false | Externalize large multimedia data to an object store. |
EHRBASE_MULTIMEDIA_THRESHOLD_BYTES | integer (bytes) | 262144 (256 KiB) | Decoded size strictly above which data is offloaded. |
EHRBASE_MULTIMEDIA_ENDPOINT | URL | none | S3-compatible endpoint. None = AWS default resolution. |
EHRBASE_MULTIMEDIA_BUCKET | string | openehr-multimedia | Target bucket. |
EHRBASE_MULTIMEDIA_REGION | string | us-east-1 | AWS region (required even for non-AWS endpoints). |
EHRBASE_MULTIMEDIA_ACCESS_KEY_ID | string | none | S3 access key id (none + no secret = anonymous). |
EHRBASE_MULTIMEDIA_SECRET_ACCESS_KEY | string (secret) | none | S3 secret access key. |
EHRBASE_MULTIMEDIA_ALLOW_HTTP | boolean | false | Allow plain-HTTP endpoints — development/test only. |
External terminology validation
Prefix EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_, separator __, optional file
EHRBASE_VALIDATION_CONFIG. Off by default (the in-process openEHR bundle is
used). Providers are a map keyed by a provider name (below shown as <NAME>,
conventionally default).
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_VALIDATION_CONFIG | path | none | Path to the terminology-validation TOML config file. |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_ENABLED | boolean | false | Activate external terminology validation. |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_FAIL_ON_ERROR | boolean | false | On TS/connectivity error, reject (fail-closed) vs accept (fail-open). |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_PROVIDERS__<NAME>__TYPE | enum{fhir} | fhir | Provider kind (FHIR R4). |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_PROVIDERS__<NAME>__URL | URL | none (required) | FHIR R4 base URL of the terminology server. |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_PROVIDERS__<NAME>__OPERATION | enum{validate_code,expand} | validate_code | Value-set membership operation. |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_PROVIDERS__<NAME>__CONNECT_TIMEOUT_MS | integer (ms) | 2000 | Per-provider connect timeout. |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_PROVIDERS__<NAME>__REQUEST_TIMEOUT_MS | integer (ms) | 10000 | Per-provider request timeout. |
EHRBASE_VALIDATION_EXTERNAL_TERMINOLOGY_PROVIDERS__<NAME>__OAUTH2_CLIENT | string | none | Name of an OAuth2 client-credentials client for the provider. |
Process / CLI
| Key | Type | Default | Description |
|---|---|---|---|
EHRBASE_HEALTHCHECK_URL | URL | http://127.0.0.1:8080/ehrbase/rest/status | Target URL for the binary’s healthcheck subcommand (container HEALTHCHECK and Kubernetes exec probes). |
What belongs in a mounted file
Env variables cannot carry lists or nested structures cleanly. Put these in the
module’s TOML file (via EHRBASE_<AREA>_CONFIG, or the Helm chart’s
config.files) instead:
- the Basic-auth user store (
[[auth.basic.users]]), - a full OIDC block with multiple audiences/algorithms,
- RBAC role-claim lists and ABAC (Cedar) policies,
- the external terminology provider map,
- ATNA TLS certificate paths and the PGP signing key.
See docker/ehrbase.dev.toml in the repository for a worked example of the
REST config file (bind address, CORS, admin, and the Basic-auth users).