This one is really just a nerdy post about how I had this fun little technical challenge from and how I solved it.
I was working on a product that required remote authentication to speak to my back end server but there were some unique constraints:
I wanted to support clones (funnily enough!) so I couldn’t pre-authenticate them with keys during fabrication
It had to speak to an MQTT server but I only wanted to give it access to it’s own channels
Here’s the system I eventually used (simplified chart at the end):
The user logs into the WebApp and requests a device authentication code
WebApp would validate if their account had the right to authenticate another device. If they did, it would issue them a 6 digit code.
The user would enter this onto the device over the device’s admin dashboard
The device would then talk to the WebApp’s backend which would then check if the code is still valid + which account to link the device to
At this stage it also sends a public key that has been generated on-device - this will be used to encrypt the MQTT credentials before sending it back to the device
The WebApp’s backend would then speak to the MQTT server which would then provision an x509 certificate + the associated private key
The server uses this to know the device’s identity and then only allows access to specific channels created just for that device in the user’s workspace
The WebApp’s backend encrypt this certificate with the RSA public key sent by the device and pass the encrypted x509 certificate back to the device
The device can decrypt the certificate and save it for future use
Note: I could have used AWS IoT fleet provisioning but the vendor lock-in is too strong with that implementation. This implementation would survive changing MQTT providers/cloud providers/etc.


