Skip to main content
Just-in-Time Registration (JITR) lets a device create itself on Golain the first time it boots. You issue one fleet bootstrap credential in the console, flash it into your image, and on first start Omega generates its own private key, asks the platform to sign it, and receives a device certificate plus the MQTT broker URL. No per-device secrets in your firmware, no manual console step per unit.
Omega generates the device private key on the device and sends only a CSR. That key never leaves the device and is never known to the platform.
The bootstrap bundle now ships two files to the device: the certificate and its private key. Enrollment requires the device to prove it holds the bootstrap key by signing its request. A certificate on its own is public material — anyone who copied it off a device or a log could previously enroll into your fleet. Treat the bootstrap key with the same care as any factory secret, and see Bootstrap credential hygiene.

When to use JITR

How it works

  1. In the console you issue a fleet bootstrap certificate and download the bundle.
  2. On first boot Omega generates an ECDSA P-256 key pair and a CSR with CN = device_name.
  3. Omega signs the request with the bootstrap private key and posts the CSR, the bootstrap certificate PEM, and that signature to the platform JITR endpoint.
  4. The platform verifies the signature against the bootstrap certificate, checks the certificate is active and belongs to the claimed org and fleet, creates the device record, signs the CSR, and decrements the certificate’s device quota.
  5. Omega writes device.crt, device.key, and metadata.json, then connects over mTLS.
The signature covers the CSR and the org, project, fleet and device name in the request, so a captured enrollment request cannot be replayed against a different device name or tenant.
Do not pre-create the device in the console. JITR creates the device record itself. If a device with the same name already exists in the project, enrollment fails with 409 DEVICE_NAME_ALREADY_IN_USE.

Before you start

There is no per-fleet “enable JITR” toggle. A fleet supports JITR as soon as it has an active bootstrap certificate.

Step-by-step

1

Open Fleet & Devices

In the console, open Fleet & Devices for your project. Pick the fleet that will own the devices (or create one first).
2

Open the fleet

Click the fleet name. You land on the Devices tab — leave it empty for JITR fleets. Devices appear here after enrollment.
3

Open Certificates

Select the Certificates tab. Active bootstrap certificates show serial, status, devices enrolled (used / quota), and expiry.
4

Issue a bootstrap certificate

Click Issue certificate. Set Device quota — how many devices this certificate may enroll. Quota is fixed once issued.Treat a bootstrap certificate as a batch credential, not a fleet-wide one: the quota is the blast radius if it leaks. Leaving the field empty takes your deployment’s configured default (25 on Golain Cloud), and the ceiling is 100 unless your instance raises it. Self-hosted operators can set a higher ceiling — see Raising the quota ceiling.Certificates default to a 30-day lifetime (90 days maximum). Issue one per production run rather than one per fleet.Click Issue certificate to create it.
5

Download the bootstrap bundle

The console shows serial, certificate ID, quota, and expiry. Download immediately.
The private key is returned exactly once and is never stored by the platform. If you close without downloading, revoke the certificate and issue a new one.
The zip contains:After download, the modal confirms the bundle was saved. Click Done.
6

Confirm the certificate is active

The Certificates table lists the new certificate as active. Use Revoke if a bootstrap certificate or its key ever leaks — already-enrolled devices keep working.
7

Place the bootstrap certificate and key on the device

Copy both files into your image. The same pair goes on every device in the fleet.
The bootstrap key must be on the device. Omega signs its enrollment request with it, and the platform rejects a request that carries no valid signature — the certificate alone is not enough to enroll.This is the trade-off that makes the certificate safe to be public: anyone who copies bootstrap.crt off a device, a log, or a support bundle still cannot enroll. Anyone who copies both can, up to the remaining quota — so keep the quota to a batch and revoke the certificate when the production run ends.
8

Add the JITR block to your Omega profile

Merge the connection.jitr block from jitr-config.yaml into your client profile (or paste the values by hand):
The downloaded jitr-config.yaml already bakes the /{org4}_{project4}/ prefixes for your fleet. You only need to export a unique OMEGA_DEVICE_NAME per device.Omitting the jitr: block entirely disables JITR.Per-device values via environment variables. device_name differs on every unit, so set it from the environment rather than baking it into the image:
The environment value wins when the named variable is set and non-empty; otherwise the YAML value stands. Load a file of these with omega-agent --env /etc/omega/device.env.
9

Confirm the root topic

The bootstrap bundle sets root_topic to /{org4}_{project4}/{{ OMEGA_DEVICE_NAME }} for your fleet. With OMEGA_DEVICE_NAME=press-01 that becomes /e023_4f19/press-01 — the path the broker ACL allows.If you leave root_topic empty, Omega defaults to omega/{device_id}, which the broker denies. mTLS connects, then every subscribe fails.
After enrollment, open the device in the console and confirm the assigned root topic matches what Omega is using.
10

Run Omega

On first start Omega enrolls, then connects. It writes three files into cert_dir:On later starts Omega skips enrollment if device.crt and device.key exist, are non-empty, and the certificate is valid with more than 24 hours remaining. Otherwise it enrolls again.
omega-agent --validate does not exercise the JITR block or attempt enrollment — it only checks profile structure. A broken jitr: block surfaces on the first real run.
11

Verify in the console

Omega logs the assigned device id and broker URL. In Fleet & Devices, open the fleet — the new device appears under Devices. Open it to confirm identity, MQTT details, and connectivity.On the Certificates tab, the bootstrap certificate’s Devices enrolled count increments by one per successful enrollment.

Enroll without starting the agent

omega-core ships a one-shot binary for factory tooling and CI. It performs the same enrollment and writes the same three files, then exits.
Output on success — exit code 0:
Any failure prints Error: … to stderr and exits 1. This binary takes no flags; every value comes from the environment, and all except OMEGA_JITR_CERT_DIR are required.

Certificate lifetime and renewal

Device certificates are valid for 90 days. Renewal runs over MQTT once the device is connected, configured under connection.cert_renewal:
Set OMEGA_CERT_RENEW_FORCE=1 to force a renewal attempt regardless of the window when testing.

If a device misses its renewal window

A device that is offline across its whole renewal window comes back holding an expired certificate. It recovers itself — you do not need to touch it:
  1. The broker accepts the expired certificate for a renewal-only session. That session may do exactly one thing: publish a CSR to its own renewal topic and receive the new chain. Telemetry, OTA and every other topic are refused, and the device is not reported online.
  2. Omega notices its own certificate has lapsed and renews before starting any modules, so nothing else publishes on the restricted session.
  3. Once the new certificate is installed the connection is re-established as a normal, unrestricted session.
This recovery grace is 14 days past expiry by default — not to be confused with renew_window_days above, which is how long before expiry a healthy device starts renewing. It is deliberately short: within it, a stolen certificate and its key could also mint a fresh certificate. Self-hosted operators can change it with CERT_EXPIRED_RENEWAL_GRACE_DAYS (maximum 90); it must be set to the same value for the broker and the cert worker, or a device gets a session it cannot use. Past the grace window the device must re-enroll: it runs JITR again with a new key, and the platform issues a new certificate for the same device record. Its device_id, history and topics are preserved.
Re-enrollment is refused while the device still holds a valid certificate. Revoke that certificate first (or disable the device), then re-enroll — otherwise anyone holding the fleet bootstrap credential could take over a device that is running normally.

Managing bootstrap certificates

Revoke immediately if a bootstrap certificate and its key leak together — that pair can enroll into the fleet up to the remaining quota. Revoking does not affect devices already enrolled with it.

Bootstrap credential hygiene

The bootstrap pair is a factory credential shared by a production run. Until per-device enrollment tokens ship, these habits are what bound the damage:
  • Issue per batch, not per fleet. Set the quota to the size of the run.
  • Revoke when the run ends. An unrevoked certificate keeps working until it expires.
  • Keep the lifetime short. The 30-day default assumes you issue per shipment; a device that boots after the certificate expires cannot enroll, so allow for warehouse and shipping time when you choose it.
  • Never log or screenshot the key. The certificate alone is harmless; the pair is not.
  • Watch the enrolled count. If Devices enrolled climbs faster than your line produces units, treat the credential as compromised and revoke it.

Raising the quota ceiling

Self-hosted operators can raise the ceiling per instance — a single-day flash of thousands of devices is a legitimate case. The value lives in the instance_configs table, so it takes effect without a new release or a restart: Set value on the row for your instance. Raising it widens what one leaked credential can do, so raise it for the run and lower it afterwards.

Disabling a device

Disabling is the reversible alternative to deleting a compromised or retired device — the record and its history stay:
  • Its certificate is revoked.
  • Any live MQTT session is terminated, not just blocked at next connect.
  • It cannot reconnect, renew, or re-enroll while disabled — JITR refuses a disabled device name.
Re-enabling does not restore the old certificate. The device re-enrolls to get new material, so plan for physical or remote access before disabling a fielded unit.

Troubleshooting

Enrollment failures are fatal to startup by design: a single request, no retry loop. Run Omega under a supervisor so transient API outages are retried by process restart.

Next steps