Host agents
Host agents are the privileged half of the MOS privilege boundary: small root-owned services that perform host actions on behalf of the unprivileged Suite Manager web app. Each one is a systemd service reachable only over its own local Unix socket (mode 0660, group mos-agent — no TCP ports, no LAN exposure), and each exposes a short list of explicit, validated operations rather than general command access.
The agents
Section titled “The agents”| Agent | Unit | What it owns |
|---|---|---|
| HTTPS | mos-https-agent | The Cloudflare DNS-01 flow: verifies the token against the zone, stores it root-only, rewrites the Caddyfile atomically with checkpoint/rollback, restarts Caddy. |
| Homepage | mos-homepage-agent | Validates and applies allowlisted dashboard YAML and the MOS-owned home route snippet; keeps a 10-checkpoint history; restarts/reloads only when content actually changed. |
| App runtime | mos-app-agent | The Docker side of app management — the largest agent, at contract version 9 with 14 capabilities. See below. |
| Backup | mos-backup-agent | Drive discovery and mounting, whole-suite backup and restore jobs (one at a time). |
| Update | mos-update-agent | Managed updates: track configuration and update jobs, each run as a transient systemd unit so an update survives the agent restarting itself. An orphaned job is marked failed after a timeout instead of blocking updates forever. |
| Lab reset | mos-lab-reset-agent | Lab installs only (USB/Hyper-V with MOS_LAB_RESET_ENABLED=1): clears disposable lab state for repeatable testing. Absent on normal installs. |
Sockets live at /run/mos-<name>-agent/agent.sock.
The app runtime agent
Section titled “The app runtime agent”The app agent is where the boundary is under the most pressure, so it’s worth spelling out. It accepts bounded structured projections and host-owned snapshot identities — never repository-relative build paths — across fourteen named capabilities:
- Runtime —
apps.multi-service.apply,apps.multi-service.stop,apps.multi-service.remove,apps.network.connect,apps.health.check. - Snapshots —
apps.package.snapshotandapps.package.snapshot.external, which copy only validated package files into the host-owned root. - Updates —
apps.package.update.stage,.build,.activate,.rollback,.promote,.reclaim, plusapps.package.remove.reclaim.
It owns two storage roots. Installed package snapshots live under MOS_APP_PACKAGE_ROOT (/var/lib/mos/app-packages, root:mos-agent, mode 2750, so Suite Manager can read but not write them); candidate downloads land under the private MOS_APP_CANDIDATE_ROOT (/var/lib/mos/suite-manager/app-candidates), the only place an unvalidated package may ever sit.
Three behaviors matter more than the list. The agent re-verifies the expected snapshot digest before it builds anything, so a candidate that changed after you previewed it is refused rather than built. Update stages are separate operations — build the candidate, activate it, then promote or roll back — so an interruption leaves a state that can be recovered or reported rather than a half-applied app. And promotion reclaims the images its own package digest names, using docker image rm without --force, so an image a container still needs simply stays. The agent also reports its host architecture, which is how Suite Manager refuses an incompatible package before a build fails halfway. Stop preserves routes, volumes, config, secrets, and snapshots; only the explicitly destructive remove deletes them.
How they’re installed and updated
Section titled “How they’re installed and updated”All agents (and the Suite Manager / Homepage / Caddy units) are generated and refreshed by one reconciliation script, scripts/reconcile-system.cjs — run at install time and again during every managed update. That’s what guarantees an update refreshes the agents along with everything else: reconciliation is the single writer of repo-owned units, sockets, groups, and the pinned Caddy binary.
Operating them
Section titled “Operating them”They are ordinary systemd services:
systemctl status mos-backup-agent # is it running?journalctl -u mos-backup-agent -e # its logssystemctl restart mos-backup-agent # the classic fixSuite Manager degrades gracefully per agent — if the Backup screen says the host backup service is unavailable, that means exactly one unit is down, and the other screens keep working. Running a managed update (or sudo node scripts/reconcile-system.cjs from /opt/mos/repo) reconverges everything.
Design rules
Section titled “Design rules”Two rules keep this layer trustworthy, and they are treated as architecture, not style:
- Agents grow by adding explicit capabilities, never by granting Suite Manager arbitrary host access. Each new need becomes a named, validated operation.
- Secrets cross the boundary minimally. App secrets are materialized per apply-request only; the Cloudflare token goes straight to a root-only file and is never readable back through any API.