Device Provisioning Pattern¶
Context¶
FlexGalaxy.AI is a multi-tenant APaaS where each account (tenant) manages its own fleet of IoT devices. The platform uses multiple backend systems — ThingsBoard for device management and telemetry, hawkBit for OTA updates, and DotID for platform API authentication — each with its own device identity and credential model.
Device provisioning is not a single event. A device may go through multiple provisioning stages across its lifecycle — from factory assembly to field deployment — each with different identity proofs, credential requirements, and target accounts.
The Provisioning Service is a dedicated microservice, separate from
DeviceAdmin, exposed at
api.flexgalaxy.com/provisioning/v1/. DeviceAdmin delegates enrollment to the
Provisioning Service and provides the device management API on top.
Provisioning Scenarios¶
Devices are provisioned at different stages of their lifecycle, by different actors, into different accounts:
Scenario 1: Factory Provisioning (Controller)¶
A core controller is produced and flashed with basic firmware at the controller factory. This is the earliest provisioning step.
Controller Factory
│
│ POST /provisioning/v1/enroll
│ {
│ "scenario": "factory",
│ "device_type": "controller",
│ "manufacturer": "syrius",
│ "serial": "CTRL-2024-001",
│ "firmware_version": "bootloader-1.0"
│ }
│ + mTLS (manufacturer CA cert)
│
▼
Provisioning Service
├── ThingsBoard: create device (basic profile, factory account)
├── hawkBit: create target (eligible for firmware updates)
└── Return: MQTT credentials + DDI token
At this stage:
The controller is registered under the manufacturer’s account
Only basic firmware and connectivity credentials are issued
No DotID M2M client (not yet a business API participant)
The controller can receive firmware updates via hawkBit DDI
Scenario 2: Assembly Provisioning (Robot)¶
Once the controller is assembled into a complete robot, the robot requests re-provisioning to install full software and transition to an operational profile.
Assembly Line
│
│ POST /provisioning/v1/enroll
│ {
│ "scenario": "assembly",
│ "device_type": "amr",
│ "parent_serial": "CTRL-2024-001",
│ "serial": "AMR-X1-2024-001",
│ "capabilities": ["navigation", "picking", "charging"]
│ }
│ + mTLS (same manufacturer CA cert)
│
▼
Provisioning Service
├── ThingsBoard: upgrade device profile (controller → AMR)
├── hawkBit: update target attributes (capabilities, type)
├── DotID: create M2M OIDC client (robot can now call platform APIs)
└── Return: full credentials (MQTT + DDI + M2M API)
At this stage:
The device record is upgraded from “controller” to “AMR” with full capabilities
A DotID M2M client is created (the robot can now call FlexGalaxy business APIs)
The device may still be under the manufacturer’s account (pre-delivery)
Scenario 3: Field Provisioning (Customer Deployment)¶
When a device arrives at a customer site (warehouse, shopping mall), it is provisioned into the customer’s account. This also covers MDM-style provisioning for tablets and PDAs.
Customer Site (warehouse, mall)
│
│ POST /provisioning/v1/enroll
│ {
│ "scenario": "field",
│ "claim_token": "tok-abc-123",
│ "device_type": "pda",
│ "serial": "PDA-2024-042"
│ }
│ (or mTLS for robots being transferred)
│
▼
Provisioning Service
├── Validate claim token → resolve customer account
├── ThingsBoard: create device (or transfer from manufacturer account)
├── hawkBit: update target tenant
├── DotID: create/update M2M client (scoped to customer account)
└── Return: operational credentials for customer environment
Field provisioning handles:
Robots transferred from manufacturer — device moves from manufacturer account to customer account, credentials are rotated
Tablets / PDAs — MDM-style enrollment using claim tokens (QR code scan)
Constrained sensors — pre-shared tokens distributed during installation
Cross-account — devices may span different accounts, organizations, and permission scopes
Scenario Summary¶
Scenario |
Actor |
Account |
Identity |
Credentials Issued |
|---|---|---|---|---|
Factory |
Manufacturer |
Manufacturer account |
mTLS (manufacturer CA) |
MQTT + DDI |
Assembly |
Manufacturer |
Manufacturer account |
mTLS (manufacturer CA) |
MQTT + DDI + M2M API |
Field (robot) |
Customer / operator |
Customer account |
mTLS or claim token |
MQTT + DDI + M2M API (rotated) |
Field (PDA/tablet) |
Operator on-site |
Customer account |
Claim token (QR) |
MQTT + DDI + M2M API |
Field (sensor) |
Installer |
Customer account |
Pre-shared token |
MQTT + DDI |
Pattern¶
Device Identity Verification¶
Different provisioning scenarios use different identity proofs:
Device Class |
Identity Method |
Verification |
|---|---|---|
Robots (AMR, cleaning) |
X.509 client certificate |
Validate against manufacturer’s subordinate CA |
PDAs / tablets |
Claim token + device serial |
Token issued during physical setup (QR code) |
Constrained sensors |
Pre-shared access token |
Token distributed during installation |
Gateways |
X.509 or claim token |
Depends on gateway type |
X.509 Certificate Chain¶
For robot-class devices, FlexGalaxy.AI uses a certificate chain:
FlexGalaxy Root CA
└── Manufacturer Subordinate CA (e.g., Syrius Robotics CA)
└── Device Certificate (e.g., AMR-X1 SN-2024-001)
The platform trusts manufacturer CAs registered through the developer portal
Each device presents its certificate during mTLS enrollment
The Provisioning Service validates the chain and extracts the manufacturer and serial number from the certificate’s Subject DN
Claim Tokens¶
For devices that cannot do mTLS (PDAs, tablets, sensors):
1. Operator generates claim tokens in bulk via API or StarGate
2. Tokens are printed as QR codes or loaded onto devices during setup
3. Device presents claim token during enrollment
4. Token maps to account + device type + priority + expiry
5. Token is consumed (single-use)
Tenant Resolution¶
The Provisioning Service resolves which ThingsBoard tenant (FlexGalaxy account) the device belongs to:
Identity Method |
Tenant Resolution |
|---|---|
X.509 cert (factory/assembly) |
Manufacturer CA → manufacturer account |
X.509 cert (field transfer) |
Claim token overrides → customer account |
Claim token |
Token contains account ID directly |
Pre-shared token |
Token was issued for a specific account |
Backend System Registration¶
After identity verification and tenant resolution, the Provisioning Service creates or updates device records in backend systems:
Step |
System |
API Call |
Result |
|---|---|---|---|
1 |
ThingsBoard |
|
Device ID, MQTT credentials |
2 |
hawkBit (via OTAForge) |
|
Controller ID, DDI security token |
3 |
DotID |
Create OIDC client (if applicable) |
Client ID, client secret (M2M) |
All systems use the same device identifier (device_id), enabling
cross-system correlation.
Credential Types Issued¶
Credential |
System |
Purpose |
Rotation |
|---|---|---|---|
MQTT access token |
ThingsBoard |
Telemetry ingestion, device mgmt |
Via Provisioning Service |
DDI security token |
hawkBit (via OTAForge proxy) |
OTA update polling |
Via Provisioning Service |
OIDC client credentials |
DotID (Keycloak) |
Business API access ( |
Via DotID API |
X.509 cert (if used) |
mTLS |
Enrollment identity |
Manufacturer-managed |
Device Lifecycle¶
┌──────────┐ ┌────────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐
│ Unmanaged │────►│ Factory │────►│ Assembled │────►│ Field │────►│ Decommissioned│
│ │ │ Provisioned│ │ Upgraded │ │ Active │ │ │
└──────────┘ └────────────┘ └──────────┘ └──────────┘ └───────────────┘
│ │ │
│ failure │ failure │ suspend
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌──────────┐
│ Rejected │ │ Rejected │ │ Suspended │
└────────────┘ └────────────┘ └──────────┘
State |
Description |
|---|---|
Unmanaged |
Physical device or component, not yet enrolled |
Factory Provisioned |
Controller registered with basic firmware, manufacturer account |
Assembled / Upgraded |
Full robot with complete capabilities, manufacturer account |
Field Active |
Deployed at customer site, customer account, fully operational |
Suspended |
Temporarily disabled (e.g., lease expired, policy violation) |
Decommissioned |
Removed from all systems, credentials revoked |
Rejected |
Enrollment failed (invalid identity, unknown manufacturer) |
Account Transfer¶
When a device moves from manufacturer to customer (or between customers):
New enrollment request with
scenario: "field"+ claim token or mTLSProvisioning Service transfers ThingsBoard device to new tenant
hawkBit target attributes updated (new tenant context)
DotID M2M client rotated (new account scope)
Old credentials revoked, new credentials issued
Emit
device.transferredevent to Kafka
Decommissioning¶
When a device is decommissioned:
Revoke ThingsBoard credentials (disable device)
Remove hawkBit target (no more OTA updates)
Delete DotID M2M client (revoke API access)
Archive telemetry data (retention policy applies)
Emit
device.decommissionedevent to Kafka
API Surface¶
Operation |
Endpoint |
Description |
|---|---|---|
|
Enroll or re-provision a device |
|
|
Get provisioning status and history |
|
|
Transfer device to a different account |
|
|
Rotate credentials across all systems |
|
|
Suspend a device |
|
|
Reactivate a suspended device |
|
|
Decommission a device |
|
|
Generate claim tokens (batch) |
|
|
List unused claim tokens |
Dependencies¶
Service |
Relationship |
|---|---|
ThingsBoard |
Creates/transfers device records and MQTT credentials |
OTAForge (hawkBit) |
Creates/updates targets and DDI security tokens |
DotID (Keycloak) |
Creates M2M OIDC clients |
Org Service |
Resolves account/tenant context, org hierarchy |
Consumed By¶
Consumer |
Usage |
|---|---|
DeviceAdmin |
Delegates enrollment, transfer, and decommission operations |
Devices |
Enroll during factory, assembly, or field deployment |
StarGate |
Admin UI for managing provisioning, generating claim tokens |
Applications |
Query device provisioning status |
Consequences¶
Benefits¶
Multi-scenario provisioning — same service handles factory, assembly, and field enrollment with different identity proofs and credential sets
Account transfer — devices can move between accounts (manufacturer → customer) with credential rotation and audit trail
Consistent identity — same device ID across ThingsBoard, hawkBit, and DotID enables cross-system correlation
Separation from DeviceAdmin — provisioning logic is complex (compensating transactions, multi-scenario, account transfer) and benefits from being an independent service with its own lifecycle
Trade-offs¶
Multi-system coordination — provisioning depends on ThingsBoard, hawkBit, and DotID all being available; enrollment fails if any is down
Compensating transactions — if one system fails mid-enrollment, partial records must be cleaned up
Custom service — this is a FlexGalaxy-specific service, not an off-the-shelf component; it must be built and maintained