Config Files
One YAML file at /etc/xerotier/xem.yaml. CLI flags win, then XEM_* environment variables, then this file, then built-in defaults. Flat scalars only; nested maps and sequences are rejected at boot.
Overview
This page documents the on-host config layer for the
XEM agent. The
Environment Variables
reference covers the matching XEM_*
overrides; chat templates are project-scoped JSON
managed through the router API and live under
Author a
Chat Template.
Keyboard: press Alt+E to jump to the next example block, Alt+Shift+E for the previous one. The chord ignores text inputs.
xem.yaml
Loaded from the path supplied by --config,
default /etc/xerotier/xem.yaml. A missing
file is a legitimate "no config" signal, so flag-only
and environment-only deployments work without an
empty stub.
The file is a flat top-level mapping of scalars
(string, integer, boolean). Nested maps and sequences
are rejected at boot with
invalidConfigFile. Keys are lowercased
before lookup.
# required
router_url: https://router.example.com
join_key: jk_xxxxxxxxxxxxxxxxxxxxxxxx
registration_name: xem-prod-us-east-01
# optional (defaults shown)
tools_dir: /var/lib/xerotier/tools
credentials_dir: /var/lib/xerotier/credentials
log_level: info
lease_renewal_interval_ms: 10000
shutdown_grace_seconds: 30
max_concurrent_executions: 20
signing_key_path: /var/lib/xerotier/agent-signing-key.hex
curve_key_path: /var/lib/xerotier/agent-curve-key.hex
queue_db_path: /var/lib/xerotier/state/queue.sqlite
router_auth_token: rt_optional_callback_token
project_external_id: proj_optional_external_id
Keys
Every key has a matching XEM_*
environment override (for example XEM_JOIN_KEY,
XEM_QUEUE_DB_PATH). The required keys
have no default; the agent refuses to start if any
is unset across CLI, environment, and file.
| Key | Default | Required | Purpose |
|---|---|---|---|
router_url |
unset | Yes | HTTPS endpoint of the router used for enrollment and the data plane. |
join_key |
unset | Yes | One-shot enrollment token issued by the router. Consumed on first boot. |
registration_name |
unset | Yes | Stable display name the router uses to track this agent across restarts. |
tools_dir |
/var/lib/xerotier/tools |
No | Directory of tool bundles the agent loads at startup. |
credentials_dir |
/var/lib/xerotier/credentials |
No | Directory of per-workspace credential files referenced by credentials_ref in tool manifests. |
log_level |
info |
No | Log verbosity. One of trace, debug, info, notice, warning, error. |
lease_renewal_interval_ms |
10000 |
No | Cadence (milliseconds) for lease renewal messages to the router. |
shutdown_grace_seconds |
30 |
No | Time the agent waits for in-flight executions to finish on SIGTERM before forcing exit. |
max_concurrent_executions |
20 |
No | Ceiling on simultaneous tool executions handled by the agent. |
signing_key_path |
/var/lib/xerotier/agent-signing-key.hex |
No | Persisted Ed25519 signing-key file used to sign messages to the router. |
curve_key_path |
/var/lib/xerotier/agent-curve-key.hex |
No | Persisted Curve25519 key-agreement private-key file. The public half is derived on load. |
queue_db_path |
/var/lib/xerotier/state/queue.sqlite |
No | SQLite file backing the outbound dispatch queue. |
router_auth_token |
unset | No | Bearer token used on router-callback requests. Without it, callback-dependent tools surface router_callback_missing. |
project_external_id |
unset | No | External project id (ws_<hex>) attached to callbacks for project-scoped routing. |
Reload Semantics
Configuration changes require a full restart.
There is no SIGHUP reload handler.
The filesystem watcher on
/etc/xerotier/xem.yaml and the
credentials and tools directories logs change
events only; it does not re-apply them.
Capability Manifest
The capability manifest is not an operator-edited
file. The agent constructs it in-process from its
registered tool descriptors and republishes on
enrollment and every lease renewal. The router
persists it server-side in
agents.capability_manifest_json.
The manifest is the allowlist. The router rejects
any tool call not present in the published
manifest. Editing a file named
manifest.json on the XEM host has
no effect on the published manifest.
Wire shape (internal reference)
The fields below are the on-wire JSON shape. Operators do not author these; the agent emits them.
| Field | Purpose |
|---|---|
schema_version | Manifest schema revision. |
agent_id | Stable agent identifier assigned at enrollment. |
display_name | Operator-visible name; mirrors registration_name. |
description | Short free-text description supplied by the tool bundle. |
shared_limits | Object with max_concurrent_executions_total, max_execution_timeout_ms, max_result_size_bytes. |
workspaces[] | Workspaces the agent is bound to. |
tools[] | Flat array; each tool carries name, domain, description, parameters_schema, risk (level, requires_approval, reversible, optional reversal_tool), credential_type, timeout_ms, idempotent, and the workspaces it applies to. |
On-Disk Layout
Default layout on a production XEM host:
/etc/xerotier/
xem.yaml
/var/lib/xerotier/
agent-signing-key.hex
agent-curve-key.hex
tools/
credentials/
state/
queue.sqlite
queue.sqlite-wal
queue.sqlite-shm
/var/lib/xerotier/must live on a persistent volume. The dispatch queue is not useful if the filesystem is ephemeral.- The Curve25519 public half is derived from the private key on load; there is no separate
.publicfile. - Logs go to stderr by default. Routing to
journald,rsyslog, or a file is the operator's responsibility. See Deployment File Layout for the systemd and container overlays.
Further Reading
- XEM Environment Variables - the
XEM_*override layer for every key above. - Deployment File Layout - systemd and container overlays.
- Author a Chat Template - project- and workspace-scoped JSON managed via the router API.