Auth & TLS
Two toggles: API-key auth and TLS. Both live under [auth] and [tls] in the TOML.
API-key auth
Every request is required to carry Authorization: ApiKey <key> when [auth] enabled = true — which is the default, so a node started without --insecure demands a key whether or not you wrote a config. Bearer <key> and Basic base64(user:<key>) are accepted too, but ApiKey is the scheme the engine documents and the one every XERJ client sends.
An admin key is auto-generated on first run if admin_api_key is blank — a 64-character hex string, written to <data_dir>/admin.key with mode 0600. The startup banner names that file and does not print the key. It is not stored next to the config, and it is reused on restart rather than regenerated.
$ cat /var/lib/xerj/admin.key
4f2c9e17b83a0d5641fe72c8b90a3d5e17c46b8f92a0e35d7148bc6a03f9e2d1
$ curl -H "Authorization: ApiKey $(cat /var/lib/xerj/admin.key)" \
http://localhost:8080/v1/indices/logs/search -d @q.json
CLI clients need the same key and do not read the config file for it: xerj autoindex takes --api-key or the XERJ_API_KEY environment variable — see the CLI reference.
TLS
Terminate TLS at the server. PEM cert and key paths are required when enabled.
[tls] enabled = true cert_path = "/etc/xerj/certs/xerj.crt" key_path = "/etc/xerj/certs/xerj.key"
Key rotation
The key is read at startup, so rotation is a restart. Delete admin.key and the next start mints and prints a fresh one; write your own 64-character hex string into it instead and that value is adopted as-is. Anything else in the file is treated as corrupt and replaced.
$ sudo rm /var/lib/xerj/admin.key $ sudo systemctl restart xerj $ sudo journalctl -u xerj | grep -A4 'First-run'
Network
bind_address defaults to 127.0.0.1: a node you have not configured is reachable from its own host and nowhere else. Set it (or pass --bind / XERJ_BIND_ADDRESS) to expose the node.
With tls.enabled = false, a non-loopback bind refuses to start — every listener would serve plain HTTP, putting the API key in every Authorization header on the wire. Either enable TLS, or declare the exposure with server.allow_insecure_network_bind = true when something in front of the node already terminates TLS. --insecure does not evade this: it clears tls.enabled, so it trips the same check.
Source · engine/crates/xerj-common/src/config.rs · engine/crates/xerj-api/src/auth.rs