Skip to content

Provisioning Workflow

What happens inside tlm-cli pms provisioning provision — a step-by-step explanation of the provisioning lifecycle.

What provisioning means

Provisioning a device does two things:

  1. Registers it in the ToloMEO platform (PMS + IoT layer) and associates it with a customer tenant.
  2. Produces a configuration file (agent.env) that the device's on-board agent needs to connect to the platform.

Until a device is provisioned it does not exist in the system. Until the agent.env file is placed on the device, the device cannot communicate with the platform.

Step-by-step

1. Existence check

The DeviceProvisioner queries the PMS to confirm the serial number does not already exist. If it does, a DeviceAlreadyExistsError is raised and provisioning stops.

2. Tenant ID resolution

The customer code (e.g. ACME) is resolved to the internal tenant ID stored in the PMS customer record. This tenant ID is what the provisioning API needs — not the human-readable code.

If the customer is not found or has no tenant ID, a CustomerNotFoundError is raised.

3. Bulk provisioning API call

A single POST /devices/provision/bulk call is made to the ToloMEO Manager REST API. This is a bulk endpoint even for a single device. The payload includes:

{
  "devices": [
    {
      "serial": "SN-001234",
      "tenant": "<tenant-id>",
      "manufacturing": {}
    }
  ]
}

On success the device record is created across PMS and the IoT layer.

4. ConnHex ID retrieval

The provisioning API populates the device's connhex_id field in PMS asynchronously. The DeviceProvisioner queries PMS for the serial number and reads the connhex_id. This is the platform-side identity token for the device.

5. Init key retrieval

The init key is fetched from the IoT API using the ConnHex ID:

GET /things/<connhex_id>
→ { "metadata": { "init_key": "..." } }

This key is a one-time secret used by the device agent to authenticate on first boot.

6. Config file generation

The init key is written into agent.env:

CONNHEX_AGENT_LICENSE_AGENT_HOST=https://registry.compiuta.com
CONNHEX_AGENT_INIT_HOST=https://apis.<instance>
CONNHEX_AGENT_INIT_ID=SN-001234
CONNHEX_AGENT_INIT_KEY=<init-key>

The file is placed at <output-dir>/<serial-number>/agent.env and must be copied to /opt/connhex/configs/agent.env on the device.

Unprovisioning

Unprovisioning is the reverse: a DELETE /devices/provision/bulk call removes the device records from PMS and the IoT layer. This is permanent and cannot be undone.

get-certificate

get-certificate still verifies the device exists in PMS (raising DeviceNotFoundError if not), then re-runs steps 4–6: it fetches the ConnHex ID and init key and re-writes the agent.env. Steps 2 and 3 are skipped — no tenant resolution or provisioning API call is made. Use this when the config file is lost or needs to be reissued.

Error handling

Error class Raised when
DeviceAlreadyExistsError Serial number already in PMS during provisioning
CustomerNotFoundError Customer code not found or has no tenant ID
DeviceProvisioningError Bulk provisioning API call failed
DeviceNotFoundError Serial number not in PMS during get-certificate or unprovision
CertificateRetrievalError IoT API did not return an init key
ConfigurationError agent.env could not be written to disk
UnprovisioningError Bulk unprovisioning API call failed

All errors are caught by DeviceProvisioner and returned as a ProvisioningResult with status=FAILED and an error_message. The CLI then calls print_error which prints to stderr and exits with code 1.