Tetra is a modular host agent and recipe renderer for the Ultramarine Server Dashboard.
It is organized around a single dispatcher with independent,
feature-gated modules for files, recipes, SELinux, services, Quadlets,
reverse-proxy, Podman, Samba, NFS, users, and virtual machines. The settings
module is always compiled so the control plane can discover basic host facts.
The production transport is an outbound WSS connection to the dashboard/control
plane (agent-connect), using mTLS for transport identity and carrying signed
command envelopes. When the agent runs inside a VM, the same JSON frame
protocol can be carried over a virtio-vsock stream.
For development and dashboard testing, the inbound authenticated WebSocket
listener (agent-ws-serve) accepts Ed25519-signed command frames from a
controller client.
The local agent-dispatch command accepts the same command envelope shape for
one-shot debugging. See docs/agent-protocol.md for
the controller-facing API, connection negotiation, and agent protocol reference.
Recipes are declared in YAML, and Quadlet generation uses Tera templates. A recipe declares metadata, UI parameters, requirements, and a list of resources to render.
- Agent protocol reference — Connection negotiation, authentication, and the full module action catalog.
- Recipe authoring guide — How to write recipes, parameters, templates, and resources.
- Architecture overview — Crate layout, dispatcher, queue, transports, and how to add a module.
- Troubleshooting — Common issues with TLS, identity, WebSocket auth, recipe rendering, SELinux, and queue backpressure.
Default build features:
filesrecipesselinuxservicesquadletsreverse-proxypodmansambanfsusersstoragenetwork
Additional optional features:
virtual-machines
Build with every module:
cargo build --all-featuresBuild with only recipe rendering and Quadlet management:
cargo build --no-default-features --features recipes,quadletsRender a recipe into container unit files and companion files:
cargo run -- render schema.yaml --templates-dir ./templates --output-dir ./quadletsPreview without writing:
cargo run -- render schema.yaml --templates-dir ./templates --dry-runParameter values are supplied as a simple YAML map:
domain: cloud.example.com
enable_redis: truePass them with:
cargo run -- render schema.yaml --values values.yaml --templates-dir ./templates --output-dir ./quadletsThe one-shot CLI accepts the same JSON command envelope used by transports:
{
"id": "cmd-1",
"module": "settings",
"action": "get_system",
"payload": {}
}Run it:
cargo run -- agent-dispatch examples/settings.command.jsonagent-ws-serve runs an authenticated WebSocket for dashboard clients. It
requires an enrolled controller Ed25519 public key before accepting commands.
The host identity is automatically generated under /var/lib/tetra/identity:
cargo run -- agent-ws-serve \
--listen 127.0.0.1:7780 \
--controller-public-key "$TETRA_CONTROLLER_PUBLIC_KEY"For non-loopback addresses, TLS is required:
cargo run -- agent-ws-serve \
--listen 0.0.0.0:7780 \
--tls-cert /etc/tetra/tetra.crt \
--tls-key /etc/tetra/tetra.keyagent-connect dials out to the dashboard/control plane and maintains a
persistent connection:
cargo run -- agent-connect --config examples/transport.json --host-id myhostThe transport config JSON contains:
{
"control_plane_url": "wss://dashboard.example.com/tetra/agent",
"client_cert_path": "/var/lib/tetra/identity/agent.crt",
"client_key_path": "/var/lib/tetra/identity/agent.key",
"server_ca_path": "/var/lib/tetra/identity/dashboard-ca.crt"
}For a VM guest with virtio-vsock enabled, run Tetra as a small test listener inside the guest:
cargo run --all-features -- agent-vsock-serve --port 2048From the VM host, connect to the guest CID and send one command JSON object.
For libvirt guests, find the CID with virsh dumpxml VM_NAME | grep -A4 -i vsock.
printf '%s' '{"id":"cmd-1","module":"settings","action":"get_system","payload":{}}' \
| socat - VSOCK-CONNECT:GUEST_CID:2048The listener reads one command per connection and writes one AgentResponse
JSON object. This is a development smoke test for host-to-guest command
dispatch over vsock.
A sample systemd unit is provided in systemd/tetra.service. It runs
agent-connect with a transport config and persists identity under
/var/lib/tetra/identity.
Tetra uses Ed25519 asymmetric key authentication for inbound WebSocket sessions. The dashboard stores the private key server-side; Tetra stores only the controller public key. Outbound WSS uses mTLS for transport identity.
Mutating host actions execute by default. Privileged actions require an in-memory, session-bound elevation grant obtained by verifying the administrator password against the host shadow database. The grant expires after a configurable TTL (default 30 minutes).
To discover enabled modules and actions, send:
{
"id": "cmd-capabilities",
"module": "agent",
"action": "capabilities",
"payload": {}
}Each module also supports its own capabilities action.
Fedora and SELinux-oriented installs can use the selinux module to inspect
SELinux status, list and set booleans, manage file-context rules with
semanage fcontext, and run restorecon after managed file changes.
Modules that create or manage paths also accept a shared selinux payload to
apply file-context rules and relabel paths as part of the same action. For
example, a Samba share path can be labeled while updating generated config:
{
"id": "cmd-samba-config",
"module": "samba",
"action": "set_config",
"payload": {
"contents": "[media]\npath = /srv/media\n",
"dry_run": true,
"selinux": {
"path": "/srv/media",
"context_type": "samba_share_t",
"recursive": true
}
}
}