Admin guide
This guide is for the person keeping an Eldric installation healthy: installation path, first admin, tenants, models, knowledge bases, monitoring, backup and updates.
Day 1
- Install Eldric from repo.eldric.ai using the supported package path.
- Create the first administrator, before the node is reachable by anyone else. A freshly installed node starts with authentication off — deliberately, because somebody has to be able to create that first account on a machine with no accounts. Until it exists, administrative endpoints answer without a credential. Creating the first user flips the node to enforcing, and it stays there.
- Apply the license or start in the allowed evaluation mode.
- Create tenants and assign administrators.
- Confirm chat, model catalogue and health checks from the public Edge.
Day 2
| Task | Where to start |
|---|---|
| Tenants and users | Admin console, tenant settings and role assignment. |
| Knowledge bases | Create KBs, upload documents, review indexing status. |
| Models | Control model visibility and defaults per tenant. |
| Monitoring | Watch health, request latency, error rates and capacity. |
| Backups | Use supported snapshot/export workflows and test restore. |
| Updates | Use package updates and documented release notes. |
Turning on role enforcement
Assigning someone the Viewer, Developer, Admin or SuperAdmin role records what they are allowed to do. It does not yet stop them: role enforcement is opt-in and off by default, so a fresh installation permits every tool call regardless of role. Two things must both be true before roles restrict anyone, and each is inert without the other.
- Enable the security module on the nodes that run tools. It is not part of the default node role set. In the admin console open Node Roles, tick
securityand save — enabling a role takes effect immediately, no restart. The node that matters is the one executing the call: on an internet-facing cluster that is the boundary node, and a boundary node without the module enforces nothing regardless of what the rest of the cluster is set to. - Switch the mode. Modes are
stub_allow(default — everything allowed),audit(decisions evaluated and logged, still allowed) andenforce(denied calls are rejected and audited). You can switch a whole node, or one tenant at a time while the rest of the installation stays permissive.
Enforcement is partial by design. Roles bind at the call sites that carry a check; routes without one keep letting the call through in the same installation, and nothing in a response distinguishes an authorised call from one that met no check. Treat it as one layer alongside boundary authentication and tenant isolation, not as the thing that decides who may do what everywhere.
Run audit before enforce. The security counters report how many calls would have been denied; a non-zero count against an account you expect to work is the signal to fix the role assignment or the policy first. Flipping straight to enforce makes that same population fail at once, in production.
The bootstrap window
Check which state a node is in before trusting it — GET /health reports it:
curl -s http://<node>:8880/health | grep -o '"auth":"[a-z]*"'
# "auth":"off" -> no account exists yet; admin endpoints answer WITHOUT a credential
# "auth":"enforce" -> a user exists; the node requires one
The window closes by itself, on either a local registration or a replicated user arriving from a peer. It is not a setting to turn on.
A fresh node answering everything looks exactly like a build that ships without authentication. That is the reason to read auth from /health rather than infer the node's posture from a request that succeeded — the two states are indistinguishable from the outside, and only one of them is safe to leave reachable.
Where authentication actually happens
Eldric authenticates at the public Edge. The daemon port each node listens on is an internal port, and the OpenAI-compatible routes served there answer without a credential by design, because cluster members call each other over them. On a node reachable from the cluster network:
curl -s -o /dev/null -w '%{http_code}
' http://<node>:8880/v1/models
# 200 on a node that serves inference — and no key was sent
curl -s -o /dev/null -w '%{http_code}
' http://<node>:8880/api/v1/cluster/topology
# 401 — same node, same call, administrative surface
A 404 on the first line does not mean that node is protected. Nodes that do not serve inference answer 404 there — still without a credential, and still on an open port. What differs between nodes is which routes they serve, not whether they authenticate. Treat the whole cluster as one boundary: if any node answers 200, the port is serving inference to whoever can reach it.
The two surfaces differ on purpose, and the design holds only while the internal port stays internal. Publish port 443 and keep 8880 restricted to the cluster network. A node whose 8880 is reachable from the internet is serving an unauthenticated inference API, no matter which roles or enforcement mode you have set — role enforcement runs behind the boundary, not in place of it.
Check it from a host that should not have access — not from inside the cluster, where the answer is 200 either way. A refused connection or a timeout is the result you want; a status code means the port is exposed.