Skip to main content
Deploying Omega is three things: put the two binaries on the device, give it a profile, and register it as an OS service so it starts on boot and restarts on failure. Omega does the service registration for you with a single command per host.

What ships to the device

Two binaries, side by side (see Build Omega for how to produce them):
The OS service is pointed at omega-launcher, never at omega-agent directly. The launcher is what resolves the current A/B agent slot at each start, so a self-update slot flip takes effect on the next restart. If you register the agent binary directly, updates that swap slots won’t take. install-service does this correctly for you — use it rather than hand-writing a unit that execs the agent.
Keep the two binaries together — by default the launcher is expected alongside omega-agent. Also place the device’s profile (say /etc/omega/config.yaml) and make sure its cert_dir is writable by the account the service runs as.

Install as a service

One command, on the device, as root/Administrator:
  • Everything after the known flags (here --client /etc/omega/config.yaml) is forwarded verbatim as the service’s runtime arguments — exactly what you’d pass to omega-agent by hand.
  • --name <service> sets the service name (default omega). Use distinct names to run more than one instance on a host.
  • --launcher-path <path> points at omega-launcher if it isn’t next to the agent binary.
Validate the profile against the binary before installing, so a bad config fails at your desk instead of on the device:
To remove:

What it creates, per OS

install-service writes a native service definition and enables it. Here’s exactly what lands where, and how to operate it afterward.
Writes /etc/systemd/system/{name}.service, runs systemctl daemon-reload and systemctl enable. The unit is Type=simple, ExecStart = the launcher + your args, with:
  • Restart=on-failure, RestartSec=5
  • After=network.target
  • Hardening: ProtectSystem=full, PrivateTmp=true, NoNewPrivileges=true, ProtectHome=read-only
Operate it:
Requires root (writing under /etc/systemd/system).

When a service won’t start

A profile Omega can’t honor is fatal by design — it will not run half-configured (see Configure → validation). On a fresh install that shows up as a service that starts and immediately exits. Omega makes that legible rather than silent:
  • Exit code 78 (EXIT_STARTUP_FAILED) — a config/startup problem, distinct from a crash.
  • A written startup-error.log next to the profile, with the exact reason (which module or capability the build doesn’t provide, a malformed field, a denied broker subscription).
  • On Windows, the same reason is also written to the Event Log, because sc.exe’s own “did not start” message says nothing useful.
So the debugging loop is: read startup-error.log (or the Event Log entry), fix the profile, re---validate, restart the service. There is no auto-fallback to a previous config — a device that’s up is one running exactly the profile you gave it.

Production checklist

  • Ran omega-agent --validate --client <profile> and it exited 0.
  • connection.server_url is mqtts://… (TLS/mTLS), not plaintext.
  • security.signed_control.enabled: true, with the HMAC key supplied via key_env (not inline).
  • security.capabilities lists only what this device needs — each one is validated against the build.
  • Secrets (*_env fields) come from the environment or a secret manager, never committed with the profile.
  • cert_dir is stable and writable by the service account, so renewal can persist new certificates.
  • First-boot identity is ready: either a device certificate is already in cert_dir, or a connection.jitr block plus the factory bootstrap key is present.
  • The service points at omega-launcher (it does, if you used install-service).

See also