06 · ENGINE

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, printed in a startup banner and written to <data_dir>/admin.key with mode 0600. 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