Skip to main content
OTA is always present in Omega (it’s core, no feature flag). It does two related jobs:
  1. Deploy artifacts to the device — files, binaries, whatever a deployment plan specifies — with signature verification.
  2. Self-update the agent binary over A/B slots, so Omega can replace itself and automatically roll back if the new version fails to come up.
The same subsystem also hosts inventory (SBOM/HBOM/PBOM) and the node capability framework.

Deploying artifacts

The platform drives a deployment by publishing to the device’s ota/control/* topics (full list in the topic reference): The device reports back on ota/report/progress, ota/report/success, and ota/report/log, and can pull pending work by publishing to ota/request.

Signature verification

Deployments are role-bound signed. Every artifact must carry a valid signature for each required role before Omega will apply it:
  • The platform role is always required — you can’t turn it off.
  • required_roles adds more roles that must also sign (e.g. a second-party approval). loosen_role is the escape hatch for a role you want to make optional.
  • Signatures are ECDSA P-256; each trusted key is identified by a key_id and fingerprint.
An artifact whose signatures don’t satisfy the required roles is rejected — a compromised URL or broker can’t push code the platform didn’t sign.
Artifact URLs must be HTTPS. allow_insecure_http: true in the OTA config lifts that for local development only — never ship it, or an on-path attacker can swap the artifact before signature checks even matter.

Self-update over A/B slots

Omega can update itself. To make that safe, the agent binary lives in one of two slotsa and b — under the runtime data_dir. The omega-launcher supervisor (which is what the OS service actually runs) execs whichever slot is currently active. This indirection is why the service must point at the launcher, not at a fixed agent binary. Enable it in the OTA config:

How an update commits — or reverts

The update is staged and then proven before it becomes permanent:
1

Stage

Omega writes the new agent binary into the inactive slot and records it as pending, with a deadline (commit_timeout from now), then restarts.
2

Trial boot

The launcher boots the pending slot as a trial. This is a probation period, not a commit — the old slot is still intact.
3

Confirm or revert

If the new agent comes up healthy within the deadline (and health_check_cmd, if set, exits 0), the update commits — the pending slot becomes active. If the deadline passes, the agent keeps crashing, or it fails MAX_BOOT_ATTEMPTS (3) boots, the launcher reverts to the previous slot and restarts into the version that was known good.
The guarantee: a self-update that doesn’t come up healthy cannot brick the device. The launcher always has a known-good slot to fall back to, and the fallback is automatic — no operator intervention, no remote hands. With auto_commit: false, a healthy trial boot waits for an explicit commit from the platform instead of committing on its own — for fleets that want a human in the loop before a new agent version becomes permanent.

OTA config reference

The ota: section of the profile:

See also