Secure IoT device provisioning is the process of giving each device a unique identity and the credentials it needs to reach your MQTT broker, without those secrets leaking along the way. This guide compares the main provisioning models, walks through a practical bootstrap flow and shows how provisioned devices connect to a ConnectMQ broker with per-device credentials.
What Provisioning Has to Achieve
Whatever model you pick, a good provisioning process delivers five properties:
- Uniqueness. Every device gets its own credential. No two devices share a secret.
- Confidentiality. The secret is never visible in plain text to people or systems that do not need it, including logs and build artifacts.
- Traceability. You can map each credential to a serial number, a batch and a customer.
- Revocability. You can disable one device without touching the others.
- Recoverability. You can re-provision a device after repair or a factory reset.
A shared password compiled into firmware fails at least three of these. It is the most common reason a single compromised unit turns into a fleet-wide incident.
Provisioning Models Compared
| Model | How the credential gets on the device | Good for | Main risk |
|---|---|---|---|
| Factory injection | Programming station writes a unique credential during manufacturing | Controlled production lines | Secrets on factory systems |
| Claim certificate or bootstrap secret | Device ships with a shared or per-batch bootstrap identity and exchanges it for a unique credential on first boot | Large fleets, contract manufacturing | Bootstrap secret abuse if not limited |
| User-assisted onboarding | Phone app or local web page delivers credentials during setup | Consumer products | Phishing, insecure local channel |
| Manual entry | Installer types credentials into a config page | Small pilots | Human error, credential reuse |
Factory Provisioning
During manufacturing, a programming station generates or retrieves a unique credential and writes it into protected storage on the device, typically together with the serial number. On microcontrollers this is often an encrypted NVS partition or a secure element; on Linux devices an encrypted file or a TPM-backed store. The station logs the mapping to your inventory system, never the secret itself in plain text.
Strengths: devices leave the factory ready to connect. Weaknesses: the factory network now handles secrets, so it needs access control and its own audit trail, and you must trust the manufacturer.
Claim Certificates and Bootstrap Flows
A claim certificate is a limited identity shared by a batch of devices. Its only permission is to call a provisioning service and request a unique, long-term identity. Several IoT platforms implement this pattern, and you can build the same idea yourself with any broker:
- The device boots with a bootstrap secret or claim certificate and its hardware serial.
- It calls your provisioning service over HTTPS, proving possession of the bootstrap secret.
- The service checks the serial against the manufacturing allowlist and that it has not been claimed before.
- The service returns a unique MQTT credential for that device and marks the serial as claimed.
- The device stores the credential in protected storage and discards the bootstrap secret, or keeps it only for re-provisioning.
Because the claim identity cannot publish or subscribe to anything, a leaked copy lets an attacker at most claim serials that are still unclaimed, and the allowlist plus one-time claiming limits even that.
User-Assisted Onboarding
Consumer devices are often provisioned by the owner through an app that connects to the device over BLE or a temporary Wi-Fi access point. Encrypt that local channel, require proof of physical presence such as a button press, and have the app fetch the device credential from your backend rather than embedding anything in the app.
A Practical Bootstrap Flow for an MQTT Broker
If your broker issues credentials itself, as a managed MQTT broker usually does, your provisioning service becomes the custodian that hands out credentials one device at a time. With ConnectMQ you issue credentials in the portal; each set includes a username, password and a client ID that is bound to those credentials. A simple, robust design:
- Issue credential sets in the portal ahead of a production batch.
- Load them into your provisioning service's encrypted store, one per expected serial.
- Let devices claim them using the bootstrap flow above.
A minimal provisioning endpoint, written in Python with Flask for illustration:
# pip install flask
import hmac
import hashlib
import json
from flask import Flask, request, jsonify, abort
app = Flask(__name__)
BOOTSTRAP_KEY = b"load-from-a-secret-manager-not-source"
# serial -> {"claimed": bool, "cred": {...}} (use a real database in production)
INVENTORY = json.load(open("batch-2026-10.json"))
def valid_proof(serial: str, nonce: str, proof: str) -> bool:
expected = hmac.new(BOOTSTRAP_KEY, f"{serial}:{nonce}".encode(),
hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, proof)
@app.post("/provision")
def provision():
body = request.get_json(force=True)
serial, nonce, proof = body.get("serial"), body.get("nonce"), body.get("proof")
if not (serial and nonce and proof) or not valid_proof(serial, nonce, proof):
abort(401)
entry = INVENTORY.get(serial)
if entry is None or entry["claimed"]:
abort(403)
entry["claimed"] = True # persist this before responding in production
return jsonify(entry["cred"]) # {"username": ..., "password": ..., "client_id": ...}
if __name__ == "__main__":
# Serve behind HTTPS (reverse proxy with a valid certificate)
app.run(host="127.0.0.1", port=8080)
In production, store nonces to prevent replay, rate-limit the endpoint, persist the claimed flag atomically and alert on repeated claims of the same serial.
Connecting a Provisioned Device
Once the device holds its credential, connecting is ordinary MQTT username password authentication over TLS. An ESP32 example with PubSubClient that reads the credential from NVS:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Preferences.h>
extern const char ROOT_CA[]; // ISRG Root X1 PEM, compiled into firmware
WiFiClientSecure net;
PubSubClient mqtt(net);
Preferences prefs;
String user, pass, clientId;
void setup() {
Serial.begin(115200);
prefs.begin("mqtt", true); // read-only namespace
user = prefs.getString("user", "");
pass = prefs.getString("pass", "");
clientId = prefs.getString("cid", "");
prefs.end();
if (user.isEmpty()) { Serial.println("Not provisioned"); return; }
WiFi.begin("YOUR_SSID", "YOUR_WIFI_PASSWORD");
while (WiFi.status() != WL_CONNECTED) delay(500);
net.setCACert(ROOT_CA);
mqtt.setServer("YOUR_BROKER_HOST", 8883);
}
void loop() {
if (user.isEmpty()) { delay(1000); return; } // wait for provisioning
if (!mqtt.connected()) {
if (mqtt.connect(clientId.c_str(), user.c_str(), pass.c_str())) {
mqtt.publish(("devices/" + clientId + "/status").c_str(), "online", true);
} else {
Serial.printf("MQTT connect failed, state=%d\n", mqtt.state());
delay(10000); // back off, do not hammer the broker
}
}
mqtt.loop();
}
Enable flash encryption and NVS encryption so the stored credential is not readable from a dumped flash chip. The details are in secure MQTT credentials on devices.
Re-Provisioning, Repairs and Decommissioning
Provisioning is not a one-time event. Devices come back for repair, get factory-reset by customers, change owners and eventually reach end of life. Plan each of these paths before the first batch ships:
- Factory reset. Decide whether a reset wipes the MQTT credential. If it does, the device needs a way back to the bootstrap flow, which means your provisioning service must allow a controlled re-claim, for example after a support ticket marks the serial as resettable.
- Repair and board swaps. When a main board is replaced, the old credential leaves with the old board. Revoke it, issue a new set and update the inventory so the serial number points to the new client ID.
- Change of ownership. For devices sold or transferred between customers, issue fresh credentials on a broker belonging to the new owner rather than moving the old ones.
- Decommissioning. Revoke the credential in the portal on the day the device leaves service, and record the date. Abandoned credentials that still work are a common source of surprise connections months later.
Each of these paths reuses the same building blocks as initial provisioning and credential rotation: issue, deliver, verify, revoke.
Provisioning Checklist
- Unique credential per device, never a fleet-wide password.
- Secrets generated or issued centrally, not invented by firmware engineers.
- Bootstrap identity limited to provisioning only, with one-time claiming and an allowlist.
- Credentials stored in encrypted storage or a secure element.
- TLS with certificate verification on every connection, including the provisioning call.
- Inventory mapping serial to client ID, without plain-text secrets.
- A tested re-provisioning and credential rotation path.
- Backoff on authentication failures; ConnectMQ blocks IPs after repeated failed logins.
Planning Capacity and Environments
Provisioning interacts with plan limits. The Serverless (Free) plan allows up to 25 connections, which is fine for a pilot; Serverless (Paid) goes up to 1,000 connections, and Dedicated or BYOC plans suit larger or regulated fleets. Keep separate brokers for development, staging and production so test devices never hold production credentials, and use the public MQTT test broker only for non-sensitive experiments.
Get Started with ConnectMQ
Provision your first devices against a cloud MQTT broker with TLS, tenant isolation and client IDs bound to issued credentials. Create a free Serverless broker at app.connectmq.com, no credit card required.
Frequently Asked Questions
What is secure IoT device provisioning?
It is the process of giving each device a unique identity and credentials, delivering them without exposure, and recording them so they can be traced and revoked later.
What is a claim certificate?
A claim certificate is a limited, often batch-shared identity whose only permission is to request a unique device credential from a provisioning service on first boot.
Should I embed MQTT credentials in firmware images?
No. A firmware image is copied many times and is often easy to extract. Write unique credentials into protected storage per device instead.
Does ConnectMQ provide a device provisioning service?
No. You issue credentials in the ConnectMQ portal and deliver them with your own factory or bootstrap process, as shown above.



