Supply Chain OTA and Ownership Pattern

Context

FlexGalaxy.AI serves a multi-party supply chain where devices pass through several organizations before reaching the end user who operates them. A typical chain includes a software developer, a robot maker, one or more distributors, and end users. Each party has its own FlexGalaxy account and needs a different level of visibility and control over the devices.

This pattern addresses five cross-cutting concerns that arise in supply chain scenarios:

  1. Auto-OTA on enrollment — devices receive the correct software automatically when they first appear in the platform

  2. Attribute-based policy targeting — policies target device classes, not individual device IDs, so they can be authored before the devices exist

  3. Cross-account OTA — a software developer in one account publishes artifacts that are deployed onto devices owned by a different account

  4. Installation tracking and license counting — the developer needs to know how many devices installed their software and how many licenses to issue

  5. Multi-tier device scoping — devices move from maker to distributors to end users, with each tier seeing only the devices it owns or operates

User Story

A software developer (SyriusSoft) builds warehouse navigation software. A robot maker (RoboMake) produces AMR robots. RoboMake wants every robot to ship with SyriusSoft’s navigation software pre-installed. The robots are sold through regional distributors, who then sell to end users.

Concrete numbers:

Party

Role

Robots

SyriusSoft

Software developer

0 (publishes software only)

RoboMake

Robot maker

Produces 100 AMR-X1 robots

China Distributor

Regional distributor

Receives 20

Japan Distributor

Regional distributor

Receives 60

US Distributor

Regional distributor

Receives 15

Singapore Distributor

Regional distributor

Receives 5

Warehouse A

End user (customer of Japan Distributor)

Buys 30

Factory B

End user (customer of Japan Distributor)

Buys 15

Actors and Accounts

Actor

Account Type

Role

FlexGalaxy Services

SyriusSoft

Developer account

Publishes navigation software artifacts and OTA policies

OTAForge (publisher), TrustMint (license issuer)

RoboMake

Maker account

Produces robots, enrolls them, distributes to resellers

DeviceAdmin, Provisioning Service

Distributors

Member accounts under RoboMake org

Receive allocated robots, resell to end users

DeviceAdmin (scoped view)

End Users

Standalone or member accounts

Operate robots, receive OTA updates

DeviceAdmin, OTAForge (DDI polling)

Account Hierarchy

SyriusSoft (Developer Account)
├── Publishes: AMR-X1 Nav Software v3.0
└── Policy: "Install on all AMR-X1 rev≥r3"

RoboMake (Maker Account / Organization Root)
├── 100 AMR-X1 robots enrolled
│
├── China Distributor (Member Account)
│   └── 20 robots transferred
│
├── Japan Distributor (Member Account)
│   ├── 15 robots (retained)
│   ├── Warehouse A (End User Account)
│   │   └── 30 robots transferred
│   └── Factory B (End User Account)
│       └── 15 robots transferred
│
├── US Distributor (Member Account)
│   └── 15 robots transferred
│
└── Singapore Distributor (Member Account)
    └── 5 robots transferred

Pattern

1. Auto-OTA on Enrollment

When a factory worker enrolls a new robot via DeviceAdmin, the device should automatically receive the correct software without manual intervention.

How It Works

Factory Worker              DeviceAdmin         Provisioning       OTAForge          Robot
     │                          │                 Service             │                │
     │  Enroll AMR-X1-001       │                    │                │                │
     │  (serial, type, model)   │                    │                │                │
     │─────────────────────────►│                    │                │                │
     │                          │  POST /enroll      │                │                │
     │                          │───────────────────►│                │                │
     │                          │                    │                │                │
     │                          │                    ├── ThingsBoard: create device    │
     │                          │                    ├── hawkBit: create target        │
     │                          │                    ├── DotID: create M2M client      │
     │                          │                    │                │                │
     │                          │  credentials       │                │                │
     │                          │◄───────────────────│                │                │
     │                          │                    │                │                │
     │                          │                    │  New target    │                │
     │                          │                    │  event         │                │
     │                          │                    │───────────────►│                │
     │                          │                    │                │                │
     │                          │                    │                │  Evaluate      │
     │                          │                    │                │  policies vs   │
     │                          │                    │                │  new target    │
     │                          │                    │                │  attributes    │
     │                          │                    │                │                │
     │                          │                    │                │  Match found → │
     │                          │                    │                │  auto-create   │
     │                          │                    │                │  rollout       │
     │                          │                    │                │                │
     │                          │                    │                │  DDI: pending  │
     │                          │                    │                │  deployment    │
     │                          │                    │                │◄───────────────│
     │                          │                    │                │                │
     │                          │                    │                │  Download +    │
     │                          │                    │                │  install       │
     │                          │                    │                │───────────────►│
     │                          │                    │                │                │
     │                          │                    │                │  Feedback:     │
     │                          │                    │                │  success       │
     │                          │                    │                │◄───────────────│
  1. Factory worker enrolls a robot via DeviceAdmin with its serial number, type (amr), model (X1), and hardware revision (r3)

  2. DeviceAdmin delegates to the Provisioning Service, which creates records in ThingsBoard, hawkBit (via OTAForge), and DotID

  3. The new hawkBit target triggers OTAForge’s policy evaluation engine

  4. OTAForge matches the target’s attributes against active rollout policies

  5. A matching policy auto-creates a rollout for this target

  6. The robot polls OTAForge’s DDI proxy, discovers a pending deployment, downloads the artifact, and installs it

  7. The robot reports installation success via DDI feedback

The entire flow is zero-touch after the initial enrollment.

OTAForge Policy Engine

OTAForge abstracts hawkBit’s native auto-assignment into its own policy engine. This is important because:

  • hawkBit auto-assignment uses target filters with a single distribution set attached — it cannot express richer policy logic (maintenance windows, battery thresholds, phased rollouts)

  • OTAForge’s policy engine evaluates Policy Service rollout policies, which support the full constraint vocabulary (target selection, maintenance windows, battery thresholds, concurrent limits, phased deployment)

  • OTAForge treats hawkBit auto-assignment as an implementation detail, not an exposed feature

Two-Tier Attribute Evaluation

Policy evaluation splits into static targeting and dynamic constraints. Both ThingsBoard and hawkBit already store device attributes that OTAForge leverages — there is no need to duplicate this data.

Source

Attribute Examples

Nature

Set By

ThingsBoard

type, model, revision, capabilities, zone, site

Static (set at provisioning, rarely change)

Provisioning Service

hawkBit

controller_id, target_type, firmware_version, update_status

Mostly static; firmware_version updates after OTA

Provisioning Service + OTAForge (post-install)

DeviceAdmin (runtime)

battery_level, task_status, connectivity

Dynamic (real-time telemetry)

Device via MQTT

The evaluation loop:

  1. Static targeting (which devices?) — OTAForge queries ThingsBoard and hawkBit attributes to build the candidate target set. This determines which devices are eligible for a rollout.

  2. Dynamic constraints (when and under what conditions?) — for each candidate, OTAForge checks real-time state from DeviceAdmin: battery level, active task status, current time vs maintenance window. This determines whether the rollout proceeds now or is deferred.

The static part leverages attributes already stored in ThingsBoard and hawkBit. The dynamic part is the new logic OTAForge adds on top.

2. Attribute-Based Policy Targeting

The software developer (SyriusSoft) creates OTA policies before the robots exist. Policies target device attributes, not device IDs.

Policy Expression

Target: type = "amr" AND model = "X1" AND revision >= "r3"
Action: Install distribution set "NavSoft-v3.0"
Constraints:
  - Battery > 50%
  - Not executing a contract
  - Maintenance window: 00:00–06:00 local time

Attribute Sources

Attribute

Set By

When

Example Value

manufacturer

Provisioning Service

At enrollment

RoboMake

type

Provisioning Service

At enrollment

amr

model

Provisioning Service

At enrollment

X1

revision

Provisioning Service

At enrollment

r3

firmware_version

OTAForge (DDI feedback)

After each update

2.5.0

capabilities

Provisioning Service

At enrollment or assembly

["navigation", "picking"]

account_id

Provisioning Service

At enrollment or transfer

acc-robo-001

org_id

Org Service

At org membership creation

org-robomake

Why Attribute-Based

Approach

Problem

Target by device ID

Developer must know device IDs before they exist

Target by account

Too coarse — would hit all device types in an account

Target by attributes (chosen)

Developer describes the class of devices; the platform matches dynamically

When RoboMake enrolls robot AMR-X1-042 with type=amr, model=X1, revision=r3, OTAForge’s policy engine matches it against SyriusSoft’s pre-existing policy and auto-creates a rollout — even though SyriusSoft has never seen this specific device.

3. Cross-Account OTA

SyriusSoft (Account S) publishes artifacts and policies. RoboMake (Account M) enrolls devices. These are different accounts. The platform bridges this boundary through the Marketplace “Get” action.

The “Get” Action

“Get” is a Marketplace action that an account administrator (or an org-wide software/service administrator via delegation) performs on a listing. “Get” does not deploy anything — it unlocks the ability to create OTA policies for the software in that account’s scope.

SyriusSoft                    Marketplace                   RoboMake Admin
     │                             │                             │
     │  Publish listing:           │                             │
     │  "NavSoft v3.0 for          │                             │
     │   AMR-X1 rev≥r3"            │                             │
     │────────────────────────────►│                             │
     │                             │                             │
     │                             │  Browse / search            │
     │                             │◄────────────────────────────│
     │                             │                             │
     │                             │  "Get" NavSoft v3.0         │
     │                             │  Scope: [org-wide]          │
     │                             │◄────────────────────────────│
     │                             │                             │
     │                             │  Grant: OTAForge may now    │
     │                             │  create policies for        │
     │                             │  NavSoft targeting           │
     │                             │  RoboMake org devices       │
     │                             │──────────────────────►OTAForge
     │                             │                             │
     │                             │  Admin creates rollout       │
     │                             │  policy for NavSoft          │
     │                             │◄────────────────────────────│

The “Get” action presents a scope choice to the administrator:

"Get" NavSoft v3.0
├── Apply to: ○ This account only
│             ○ Organization-wide (all member accounts)
└── [Confirm]

All cross-account OTA — including OEM partnerships — follows the “Get” flow. There is no separate back-channel for direct grants.

Device-Bound vs Application Software

Not all software behaves the same way after device transfer. The platform distinguishes two categories:

Category

Example

Who “Get”s

Policy Targets

License

OTA After Transfer

Device-bound

RobotOS, bootloader

Maker

manufacturer = "RoboMake"

Permanent, free

Always — policy targets maker attribute, not owning account

Application

NavSoft, analytics agent

Whoever wants it

Account or org scope (chosen at “Get” time)

Per developer’s license policy

Only if new owner has “Get”-ed it

Device-bound software targets the manufacturer attribute, which never changes regardless of who owns the robot. When RoboMake “Get”s the operating system and creates a policy targeting manufacturer = "RoboMake", that policy matches every RoboMake robot forever — through every transfer from maker to distributor to end user. No propagation logic is needed.

Application software targets account or org scope. When a device transfers to an account outside the org, the new owner must “Get” the software independently. This gives each owner explicit consent control.

Version Scoping

The software developer configures version scoping when creating the Marketplace listing. This controls whether a “Get” covers future versions:

Developer Setting

“Get” Behavior

All versions

New versions auto-available for policy targeting — no re-“Get” needed

Major version only

“Get” covers v3.x; v4.0 requires a new “Get”

Exact version

Each version requires an explicit “Get”

This gives the developer control over the upgrade path — a free tool might cover all versions, while a paid product might require re-“Get” (and re-licensing) per major version.

4. Installation Tracking and License Counting

SyriusSoft needs two pieces of information:

  1. How many devices installed my software? (OTA tracking)

  2. How many licenses should I issue/count? (License management)

These are tracked by different services:

Concern

Service

Mechanism

OTA installation status

OTAForge

DDI feedback from devices (success/failure/progress)

License issuance

TrustMint

License created and bound to device identity

Aggregate business dashboards

Marketplace

Developer portal aggregates OTAForge + TrustMint data

ThingIO remains focused purely on device telemetry (battery, position, sensors). Business metrics — installation counts, license utilization, “Get” analytics — are aggregated by the Marketplace developer portal, which calls OTAForge and TrustMint reporting APIs.

Installation and License Timeline

Event

Trigger

OTAForge

TrustMint

Robot enrolled

Provisioning Service

Target created

Policy matched

OTAForge policy engine

Rollout created

Download started

DDI poll

Status: downloading

Install completed

DDI feedback: success

Status: installed

Depends on license issuance policy

Install failed

DDI feedback: error

Status: failed, retry policy applies

License revoked

Admin action or policy

License revoked

Policy-Driven License Issuance

The license issuance trigger is not hardcoded — it varies by software type and license type. The software developer defines a license issuance policy when creating the Marketplace listing. TrustMint consults this policy to determine when to issue a license.

Software/Applet ID
    → query software type + license type
        → query license issuance policy
            → apply policy to determine trigger event

Software Type

License Type

Issuance Trigger

Example

Firmware

Per-device perpetual

On successful OTA install

RobotOS v2.0 — license issued when DDI reports success

SaaS applet

Subscription

On explicit activation

Analytics agent — device calls license API after first run

Map data

Per-update consumable

On download completion

Building A floor plan — license consumed on each download

ML model

Per-device, version-locked

On successful OTA install + model validation

Obstacle detector — license issued after model passes self-test

This means a Marketplace listing must include a license policy definition. The developer cannot publish an offer without specifying how and when licenses are issued.

Developer Visibility

SyriusSoft sees aggregate business data through the Marketplace developer portal:

Metric

Source

Total devices matched by policy

OTAForge (rollout targets)

Successful installations

OTAForge (DDI feedback)

Failed installations

OTAForge (DDI feedback)

Active licenses

TrustMint

Installation trend over time

Marketplace portal (aggregates OTAForge data)

License utilization

Marketplace portal (aggregates TrustMint data)

“Get” count and adoption

Marketplace portal (own data)

5. Multi-Tier Device Scoping

As devices move through the supply chain, ownership transfers and visibility rules change.

Ownership Transfers

Transfer

Mechanism

What Happens

Maker → Distributor

DeviceAdmin POST /devices/{id}/transfer

Provisioning Service updates ThingsBoard tenant, hawkBit target attributes, DotID M2M client scope; old credentials revoked

Distributor → End User

Same transfer API

Same credential rotation; device now scoped to end user’s account

Each transfer follows the device provisioning pattern: ThingsBoard device moves to new tenant, hawkBit target attributes update, DotID M2M client is rotated, and a device.transferred event is emitted to Kafka.

Transfer Sequence

Japan Distributor           DeviceAdmin        Provisioning        Backend Systems
       │                        │                Service                 │
       │  Transfer 30 robots    │                   │                    │
       │  to Warehouse A        │                   │                    │
       │  (batch)               │                   │                    │
       │───────────────────────►│                   │                    │
       │                        │  For each device: │                    │
       │                        │──────────────────►│                    │
       │                        │                   ├── TB: move tenant  │
       │                        │                   ├── hawkBit: update  │
       │                        │                   ├── DotID: rotate    │
       │                        │                   │   M2M client       │
       │                        │                   │                    │
       │                        │                   │  device.transferred│
       │                        │                   │───────────────────►│ Kafka
       │                        │                   │                    │
       │                        │  Transfer complete│                    │
       │                        │◄──────────────────│                    │
       │  200 OK (batch result) │                   │                    │
       │◄───────────────────────│                   │                    │

Visibility Rules

Org Service models the account hierarchy. IAM Identity Center grants cross-account visibility. The rules:

  • Downward visibility — a parent account can see devices in child accounts (read-only)

  • No sibling visibility — distributors cannot see each other’s devices

  • Upward visibility — not granted by default; an end user does not see the maker’s other devices

Actor

Sees

Count

Mechanism

SyriusSoft

Installation + license metrics (aggregate, not device-level)

OTAForge + TrustMint reporting

RoboMake

All 100 robots across all distributors

100

Org Service (org root) + IAM Identity Center (read-only downward)

China Distributor

Own 20 robots only

20

Account-scoped DeviceAdmin

Japan Distributor

Own 15 + Warehouse A’s 30 + Factory B’s 15

60

Org Service (parent) + IAM Identity Center (read-only into children)

US Distributor

Own 15 robots only

15

Account-scoped DeviceAdmin

Singapore Distributor

Own 5 robots only

5

Account-scoped DeviceAdmin

Warehouse A

Own 30 robots only

30

Account-scoped DeviceAdmin

Factory B

Own 15 robots only

15

Account-scoped DeviceAdmin

OTA Continuity After Transfer

OTA behavior after device transfer depends on the software category:

  • Device-bound software (OS, bootloader) — policies target the manufacturer attribute, which never changes. OTA continues automatically through every transfer with no action required by the new owner.

  • Application software — policies are scoped to the account or org that “Get”-ed the software. If the device transfers to an account within the same org (and the “Get” was org-wide), OTA continues. If the device transfers to an account outside the org, the new owner must “Get” the software independently for OTA to resume.

Telemetry Transfer Rules

When a device transfers between accounts, the handling of historical telemetry data depends on the telemetry type. Transfer rules are stored in the Policy Service and executed by the Provisioning Service during the transfer flow.

Telemetry Type

On Transfer

Rationale

Device health / diagnostics

Follows device

Safety and warranty — new owner needs full history

Operational metrics (battery cycles, motor hours, error counts)

Follows device

Maintenance scheduling requires full history

Alerts and incident records

Follows device

New owner needs to know past incidents

Task execution logs

Stays in source account

Task data belongs to the operator who ordered it

Location / trajectory history

Stays in source account

May contain facility layout information

Application-specific telemetry

Configurable per app

App developer defines the transfer rule via policy

The telemetry transfer policy is consulted during the device.transferred event processing. The Provisioning Service orchestrates the data movement (or retention) across ThingsBoard tenants according to the applicable rules.


Services Involved

Service

Plane

Role in This Pattern

DeviceAdmin

Data

Enrollment UI, transfer API, device fleet view

OTAForge

Data

Artifact storage, policy engine, auto-rollout, DDI proxy, installation tracking

ThingIO

Data

Device telemetry only (battery, position, sensors) — not business metrics

DotID

Identity

Account authentication, M2M client lifecycle

Org Service

Identity

Account hierarchy (maker → distributor → end user)

IAM Identity Center

Identity

Cross-account read-only visibility grants

Marketplace

Ecosystem

“Get” action (cross-account OTA consent), developer portal (business metrics aggregation)

TrustMint

License issuance on successful installation

Provisioning Service

Multi-system device registration and credential management

Policy Service

Governance

Rollout policy storage and evaluation


Design Decisions

The following questions were raised during design and have been resolved:

#

Question

Decision

Rationale

1

OTAForge auto-assignment: own policy engine vs hawkBit native?

Own policy engine. OTAForge builds a custom evaluation loop with two-tier attribute evaluation — static targeting from ThingsBoard/hawkBit attributes, dynamic constraints from DeviceAdmin runtime state.

hawkBit’s native auto-assignment cannot express maintenance windows, battery thresholds, or phased rollouts.

2

Cross-account OTA: Marketplace “Get” vs direct Org Service grant vs both?

Marketplace “Get” only. All cross-account OTA — including OEM partnerships — uses the “Get” action. No direct back-channel.

Single, consistent consent model. “Get” scope (account vs org-wide) gives flexibility. Device-bound software targets manufacturer attribute, so it persists through transfers without propagation logic.

3

License issuance trigger: enrollment vs install vs activation?

Policy-driven, per listing. Developer defines a license issuance policy when creating the Marketplace listing. TrustMint consults this policy.

Different software types need different triggers (firmware: on install; SaaS: on activation; map data: on download). No single hardcoded trigger works for all cases.

4

ThingIO scope: IoT telemetry only, or also business metrics?

IoT telemetry only. Business metrics (installations, licenses, “Get” analytics) are aggregated by the Marketplace developer portal.

Business data is closer to software than to devices. Marketplace portal calls OTAForge and TrustMint reporting APIs. ThingIO stays focused on device data.

5

Telemetry history on transfer: follows device, stays, or splits?

Type-dependent, policy-driven. Transfer rules are stored in Policy Service and executed by Provisioning Service during transfer. Device health follows device; task logs stay in source; app telemetry is configurable.

Different telemetry types have different ownership and compliance characteristics. A single rule doesn’t fit all types.


Consequences

Benefits

  • Zero-touch software installation — devices receive the correct software automatically at enrollment, with no manual rollout creation or CI/CD coupling

  • Pre-deployment policy authoring — software developers can create and test OTA policies before any target devices exist, using attribute-based targeting

  • Decoupled artifact publishing and rollout — CI/CD pipelines publish artifacts; policies decide when and where to deploy; these are separate concerns owned by separate actors

  • Granular multi-tier visibility — each party in the supply chain sees exactly the devices it owns or manages, enforced by Org Service hierarchy and IAM Identity Center grants

  • Consistent transfer mechanics — device ownership transfer is a single API call that orchestrates ThingsBoard, hawkBit, and DotID atomically via the Provisioning Service

  • Decoupled tracking — OTA installation status (OTAForge) and license counting (TrustMint) are separate concerns, enabling independent evolution and different business models

Trade-offs

  • “Get” required for application OTA — when a device transfers to an account outside the original org, the new owner must “Get” the application software independently for OTA to resume; device-bound software (OS) is unaffected since it targets the manufacturer attribute

  • Policy targeting precision — attribute-based targeting depends on correct and consistent attribute values at enrollment; if a device is enrolled with the wrong model or revision, the policy will not match (or will match incorrectly)

  • Transfer latency — each device transfer is a compensating transaction across three systems (ThingsBoard, hawkBit, DotID) plus telemetry migration per transfer rules; batch transfers of many devices may take significant time

  • License policy complexity — developers must define a license issuance policy at listing time; incorrect policy configuration could lead to premature or missed license issuance

  • Telemetry transfer rule management — type-dependent telemetry transfer rules add operational complexity; misconfigured rules could lead to data loss or data leakage between accounts