In the previous post of this series - Compose Apps for IoT: Why They Matter and How ComposeCtl Helps we explored how to package, publish, pull, and run Compose Apps in a consistent and reproducible manner. We also highlighted several critical gaps that must be addressed to enable more reliable and security-focused OTA delivery across production fleets.
In particular:
- Device authentication and ensuring that only trusted, registered devices can pull updates or access metadata about available versions.
- Notifying devices about new App versions and enabling remote or automated update triggering.
- Verifying update metadata and App authenticity/integrity, so that what a device installs is exactly what was published.
These aren't theoretical concerns, they're the exact failure modes covered in our guide to maintaining a secure fleet of devices.
fioup, together with a Container-Only Factory in the FoundriesFactory platform, helps to address all of these gaps. It provides security-focused, superior, and highly optimized OTA software updates built specifically for Compose Apps on IoT, edge, and embedded devices.
How a Device and FoundriesFactory Can Trust Each Other
A security-focused OTA system begins with superior IoT device identity management; specifically mutual trust between a device and the backend. In our solution, this trust is established during a one-time device registration process. Specifically, when a device is registered using fioup register command, the tool:
- Generates a unique device key pair and a CSR on the device (certificate signing request containing device public key).
- Sends the CSR to the FoundriesFactory backend.
- Receives:
- a signed device certificate that is signed by the Factory Device CA,
- the Factory Root CA, which the device will use to verify the identity of backend services.
More details about this process can be found here. This is the guide on device registration with the FoundriesFactory platform using fioup.
Once a device is registered with fiuop register command, then both sides gain the ability to authenticate each other using mutual TLS (mTLS):
- The device presents its signed certificate, proving it is an authorized member of the Factory.
- The Device Gateway presents its server certificate, signed by the Factory Root CA, proving it is the legitimate backend.
This mutual authentication is foundational to fioup. It is designed so that:
- Unauthorized devices cannot access OTA metadata or pull Compose App updates.
- Devices only communicate with the genuine Factory backend, reducing the risk of man-in-the-middle attacks.
- All data — including update manifests and registry credentials — flows over encrypted, authenticated channels.
Once mutual trust is established, the device can use the Device Gateway as its single entry point for:
- Fetching Compose App update metadata
- Downloading container images (via a special Docker credential helper)
- Receiving notifications about new versions
Once a device is registered and trusted, the next challenge is to produce a new version of Compose Apps, publish them, and let a device know that the new version is available.
How FoundriesFactory Operator Can Generate and Publish Update
In a container-only setup, the concept of a Target in FoundriesFactory plays a central role in managing updates. Simply put, a Target is a specific set of Compose Apps at fixed versions. It defines exactly which Compose Apps should be deployed and running on devices.
At the technical level, a Target is represented as a JSON file containing a list of Compose App URIs along with their SHA256 digests. This ensures that each Target is consistently reproducible and verifiable, making OTA updates and deployments predictable and security-focused.
Effectively, the digest URI refers to an OCI image manifest, and the hash included in the URI is the SHA256 sum of that manifest. The manifest itself contains URIs with hashes for the components the Compose App consists of, and so on. Conceptually, this forms a Merkle tree, with the Compose App URI pointing to the tree’s root. This design allows the integrity of the entire Compose App to be verified.
Therefore, in the context of FoundriesFactory, generating an update is synonymous with generating a Target. This process consists of the following steps:
- Building the container images that the Target’s Compose Apps depend on.
- Packaging and publishing the Target's Compose Apps, each of which references the images built in step 1.
- Creating and signing a new Target that refers to the Compose Apps produced in step 2.
FoundriesFactory platform provides convenient mechanisms to perform all three steps and produce a new Target. Specific details about this process can be found in the creating first target guide.
To provide more flexibility, it is also possible to perform the first two steps outside FoundriesFactory. For example, it can be done by implementing a custom workflow or CI pipeline that builds container images and produces the Compose Apps that use them. The technical details for doing this are described in the Custom CI guide.
It is also worth mentioning that FoundriesFactory platform introduces the notion of a tag. Each Target has one or more tags associated with it. By default, a Target is assigned a tag that corresponds to the containers.git branch from which it was created. You can run fioctl targets list command to see a list of available targets and tags assigned to it, e.g.
VERSION TAGS APPS ORIGIN ------- ---- ---- ------ 3 main simple,test-case-001 docs 4 main simple,test-case-001,test-case-003 docs ... 23 main,stable http-server,simple,test-case-001,test-case-003
How Devices Discover When an Update Is Available
Once a device is registered and trusted, and a new Target is built and published, then the next challenge is ensuring it knows when a new Target is available. fioup provides two mechanisms for update discovery: on-demand checks and autonomous background monitoring, aka the daemon mode.
A device can see only those Targets that have the tag the device is configured with. The device’s tag can be set during registration using the --tag option. Later, the tag can be changed remotely with the fioctl device config updates --tag command. A user can check which tag is assigned to a device by running fioctl device show remotely or fioup whoami directly on the device.
H3 On-demand Update Checks
A user or application can manually query the FoundriesFactory backend using:
fioup check
This command performs a request over mTLS to fetch the latest list of available Targets with the tag that is set for a device. If a newer version exists, the "check" command reports it and allows the user to take further action:
fioup fetch <version>— download all device apps of the specified versionfioup install <version>— stops the currently running Apps and installs their updated versionfioup start <version>— starts the fetched and installed Apps the new versionfioup update— fetch, install, and start the newest available version of Apps in a single step
This API/interface is ideal for interactive devices or systems where updates are triggered manually or scheduled by some other software running on a device.
H3 Autonomous Background Updates (aka daemon mode)
For unattended devices, a reality central to IoT fleet management, manual checks are not enough. To support these scenarios, fioup can run as a background process:
fioup daemon
The fioup debian package includes a systemd service that runs the daemon and can be enabled and started on a device. In this mode, it periodically:
- Contacts the Device Gateway
- Checks whether a newer Target is available.
- Automatically performs the update (download → install → start)
This helps devices stay up-to-date without human intervention.
How fioup Verifies Update Metadata and App Integrity
Authenticating metadata via mTLS. All update metadata is fetched exclusively through the Device Gateway over a mutually authenticated TLS connection. This ensures:
- The device is talking to the legitimate Factory backend
- Only registered devices can access metadata
- The connection is encrypted and tamper-resistant
- Metadata cannot be spoofed or injected by unauthorized parties
App authenticity and integrity via the registry.
When
fioupfetches Compose Apps, at first it must obtain an auth token through mTLS communication with Device Gateway:- Authentication using the device’s certificate
- Access only to Apps the device is allowed to pull
Container images also come with built-in OCI integrity checksums, and
fioupensures these match during pull. If any layer is corrupted or modified, the fetch fails.
What's Next in Security-focused OTA for Edge Devices
There is still more ground to cover in this space. Upcoming posts in this series include a walkthrough of the comprehensive OTA workflow. From publishing to installation using fioup and the FoundriesFactory service. You will see exactly how an App update moves through the platform’s pipelines, how devices discover the new version/Target, and how fioup fetches, installs, and starts the updated Compose App on the device. Keep an eye out for our upcoming posts.
If you want to get started exploring the platform right away you can sign up for our free Community Edition
Alternatively you can book a demo to see how FoundriesFactory can accelerate your development.
