Configuration

Where the file lives

Search order:

  1. --config <path> CLI flag
  2. XTR_CONFIG=<path> env var
  3. ./xtr.yaml or ./xtr.yml in the working directory
  4. Built-in defaults (no file required)

Boot log says which won:

INFO xtr_on_rust: loaded config from ./xtr.yaml

Full annotated xtr.yaml

dsl_path: ./DSL                          # tree of *.yml DSL files (SOAP + REST)
port: 8080

xroad_instance: ee-test                  # → {{generate.instance}} (SOAP envelope)
                                         # → X-Road-Client instance (REST header)
xroad_protocol_version: "4.0"            # → {{generate.protocol_version}} (SOAP only)
                                         # must be "4.0" or "4.1"

client_data:                             # X-Road identity XTR presents
  member_class: GOV                      # GOV / COM / NGO / NEE
  member_code: "70000000"                # your organisation's registry code
  subsystem_code: my-subsystem           # what you registered with RIA
  # → {{{generate.client}}} in SOAP envelopes
  # → X-Road-Client: {instance}/{class}/{code}/{subsystem} on REST

wsdl_watch_dir: ./wsdl                   # auto-generate SOAP DSLs from WSDLs
                                         # (unset = feature off, hand-written only)
                                         # REST-lane is NOT affected — REST DSLs are
                                         # always hand-written.

wsdl:                                    # WSDL ingestion trust boundary (SOAP lane only)
  allow_http_upstream: false             # opt-in for plaintext http upstreams
  upstream_host_allowlist: []            # optional hostname pinning
  # upstream_host_allowlist:
  #   - ariregxmlv6.rik.ee
  #   - jvis.envir.ee

expose_soap_fault_detail: false          # echo raw upstream fault to REST callers
                                         # (SOAP lane only — REST lane doesn't
                                         # translate faults; upstream passes through)

security_server:                         # X-Road Security Server routing (mTLS)
  # Required by REST DSLs and any SOAP DSL without `service:`.
  # Unused if you only run direct-HTTPS SOAP DSLs like Ariregister.
  url: https://out.test.x-tee.ee:5500/   # YOUR Security Server, port 5500 (message)
  keystore_path: /app/ssl/xtr-client.p12 # PKCS12 client identity
  keystore_password_env: XTR_KEYSTORE_PASSWORD
  # Almost always needed for real X-Road: the SS's TLS cert is
  # issued by an operator-managed private CA that isn't in the
  # system trust store. Point at the CA bundle PEM.
  trust_ca_path: /app/ssl/xroad-ca.pem   # optional; PEM CA bundle

limits:                                  # resource ceilings
  max_request_bytes: 1048576             # 1 MiB inbound  → 413 on overflow
  max_response_bytes: 16777216           # 16 MiB upstream → 502 on overflow
  request_timeout_secs: 30               # per outbound   → 504 on overflow

Fields

Grouped by which lane needs them. "Both" means the field is consulted by SOAP and REST DSLs alike.

Runtime

FieldDefaultLanePurpose
dsl_path./DSLBothDirectory walked for *.yml / *.yaml DSL files.
port8080BothHTTP listen port.
limits.max_request_bytes1048576 (1 MiB)BothInbound REST body cap. Overflow → 413.
limits.max_response_bytes16777216 (16 MiB)BothUpstream response cap. Overflow → 502, connection torn down.
limits.request_timeout_secs30BothPer outbound request. Timeout → 504.

X-Road identity

FieldDefaultLanePurpose
xroad_instanceee-testBothSOAP: {{generate.instance}}. REST: instance segment of URL + X-Road-Client.
xroad_protocol_version"4.0"SOAP{{generate.protocol_version}}. Boot-validated: must be "4.0" or "4.1" (audit-v1 M1). Not sent on REST — the REST protocol has its own version (r1, hard-coded).
client_data.member_class""BothSOAP: <xroad:client>. REST: X-Road-Client. Empty skips sidecar identity check.
client_data.member_code""BothSame as above.
client_data.subsystem_code""BothCorrectly spelled (fixes JVM bug #1). Same as above.

WSDL folder-drop (SOAP only)

FieldDefaultLanePurpose
wsdl_watch_dirabsentSOAPFeature off when unset. See WSDL folder-drop.
wsdl.allow_http_upstreamfalseSOAPWhen false, <soap:address> URLs must be https://. Set true only for local test setups. Audit-v1 C1.
wsdl.upstream_host_allowlist[]SOAPOptional. When non-empty, every WSDL upstream host must appear on the list. Closes the DNS-rebinding lane. Audit-v1 C1.

SOAP fault exposure

FieldDefaultLanePurpose
expose_soap_fault_detailfalseSOAPWhen false, upstream SOAP Fault.detail is stripped from REST responses and faultstring is capped at 200 chars; server logs still carry the full detail at warn! level. Set true only inside trusted environments. Audit-v1 H3. Does not apply to REST DSLs — REST faults come from the provider service, not from XTR.

Security Server (mTLS)

FieldDefaultLanePurpose
security_serverabsentBothRequired by REST DSLs. Required by SOAP DSLs that omit service:. Absent → those DSLs error at request time.
security_server.urlrequired if section setBothURL of YOUR Security Server (not the central authority's). Must be https:// (see doctor rule fatal-rest-ss-not-https). Standard port is 5500 for the message channel; 4000 is the admin UI (do not use).
security_server.keystore_pathrequired if section setBothPKCS12 identity file for mTLS. Same file serves both lanes.
security_server.keystore_password_envXTR_KEYSTORE_PASSWORDBothEnv var name to read the PKCS12 password from. Never a default value — fixes JVM bug #16.
security_server.trust_ca_pathabsentBothOptional PEM CA bundle used to verify the Security Server's TLS cert. Real X-Road SS certs are typically behind an operator-managed private CA that isn't in the system trust store; without this the handshake fails with unknown issuer.

Environment variables

VariablePurpose
XTR_CONFIGAlternative path to xtr.yaml (bypasses cwd search).
XTR_KEYSTORE_PASSWORDPassword for the PKCS12 identity. Required whenever security_server: is set.
RUST_LOGtracing_subscriber filter (info, debug, xtr_on_rust=trace, …).

Validating your config before deploying

Run xtr-on-rust doctor (shipped in the same image) — it walks the loaded config, emits FATAL / BREAK / WEAK / INFO findings, and exits non-zero when something will fail at boot or when a stronger security posture is available. See Doctor & migration for the full rule catalogue — including the REST-lane codes that flag missing SS, non-HTTPS SS URL, empty target fields, and identifier-charset issues.

Startup validation

Every SOAP DSL's Handlebars envelope is compiled at boot. A malformed template blows up on startup with the offending file path — not on the first live request. REST DSLs have no template and are validated against required-fields presence + spec identifier charset at load time.

No hot reload

Config, DSLs, and WSDLs are read once at boot. Restart to apply changes.