Task -Design an MQTT topic and security structure with Mosquitto as the MQTT broker for a network of 100s of Parking lot sensors.
Overview
In this design example we take the case of a network of parking sensors. Sensors will be sending an occupied/unoccupied state message as well as supplementary information like battery level,signal level IP address etc.
Data is not confidential and not critical.
A control dashboard application will receive the data and process as necessary
Topic and Payload Structure
A starting structure is shown below. All messages will be sent as JSON encoded data.
parking/
├── sensors/
│ ├── zone1/
│ │ ├── sensor001/
│ │ │ ├── status (e.g., “occupied”, “vacant”)
│ │ │ ├── battery (e.g., “80%”)
│ │ │ ├── signal (e.g., “strong”, “weak”)
│ │ │ ├── connected (e.g., “online”, “offline”)
│ │ ├── sensor002/
│ │ ├── …
│ ├── zone2/
│ ├── …
├── commands/
│ ├── reset/
│ │ ├── all
│ │ ├── zone1
│ │ ├── sensor001
│ ├── update-firmware/
│ │ ├── all
│ │ ├── zone1
│ │ ├── sensor001
├── alerts/
│ ├── low-battery/
│ │ ├── sensor001
│ │ ├── sensor045
│ ├── malfunction/
│ │ ├── sensor120
│ │ ├── sensor234
│ ├── disconnected/
│ │ ├── sensor050
│ │ ├── sensor123
├── analytics/
│ ├── occupancy/
│ │ ├── zone1
│ │ ├── zone2
│ │ ├── total
│ ├── usage-patterns/
│ ├── average-duration/
Explanation:
sensors/zoneX/sensorYYY/ → Each sensor reports status, battery, and signal strength.
commands/ → Commands to reset, update firmware, or send other instructions.
alerts/ → Separate topics for low battery, malfunction, or other issues.
analytics/ → Aggregated data for parking usage and occupancy statistics.
connected status under each sensor to indicate if it’s online or offline.
alerts/disconnected/ for tracking sensors that have lost connection.
Possible Enhancements
Include a time stamp for each sensor attribute e.g. battery,signal etc
Example Topics and MQTT payloads
Topic: parking/sensors/zone1/sensor001/status
Payload: JSON
{
“value”: “occupied”,
“timestamp”: “2025-03-23T12:34:56Z”
}
Payload:
{
“value”: “online”,
“timestamp”: “2025-03-23T12:37:15Z”
}
Using Sparkplug For MQTT
The topic structure does resemble the Sparkplug topic structure. However adopting the Sparkplug topic and payload structure is a consideration so here is what chatGPT has to say:
Sparkplug is a better option than plain JSON when dealing with IIoT (Industrial IoT) applications that require structured payloads, state awareness, and efficient bandwidth usage. It provides data modeling, compression, and device state tracking out of the box.
However I would go for JSON data as it is much easier to work with than Google Protocol buffers.
QOS and Retained
Occupancy data can use a QOS of either 0 or 1. Generally 1 is the default choice but as this data is not really critical I would opt for a QOS of 0 unless the network was unreliable.
For occupancy data,will and birth messages the retained flag should also be set.
Designing an ACL (Access Control List) for MQTT Sensors on Mosquitto Broker
The sensors will both send data and receive commands. It is important that sensors are restricted to sending data on their own topic and that only authorised devices are able to send commands.
An ACL (Access Control List) in Mosquitto controls which clients (sensors, gateways, admins) can publish and subscribe to specific topics.
Below is a structured ACL design for your parking lot sensor system, considering security and scalability.
Roles:
-
Sensors (
sensor_XXX
) → Can only publish their own data. -
Gateways (
gateway_XXX
) → Can publish and subscribe to all sensors in their zone. -
Admin (
admin
) → Full access to all topics.
Notes: although the ACL uses the user name it is not necessary to have a passwords file unless you are also using user name and password authentication.
The following file was suggested by ChatGPT
# =========================== # ACL for MQTT Parking System # =========================== # ----- Admin Full Access ----- user admin topic readwrite parking/# # ----- Gateway Access ----- # Each gateway can publish and subscribe to its zone's sensors. user gateway_zone1 topic readwrite parking/sensors/zone1/# topic readwrite parking/alerts/zone1/# topic readwrite parking/commands/zone1/# user gateway_zone2 topic readwrite parking/sensors/zone2/# topic readwrite parking/alerts/zone2/# topic readwrite parking/commands/zone2/# # ----- Sensor Access ----- # Each sensor can only publish to its own topic and read commands for itself. user sensor_001 topic write parking/sensors/zone1/sensor001/# topic read parking/commands/zone1/sensor001/# topic read parking/alerts/disconnected/sensor001 user sensor_002 topic write parking/sensors/zone1/sensor002/# topic read parking/commands/zone1/sensor002/# topic read parking/alerts/disconnected/sensor002 # (Repeat for all sensors...) # ----- Public Read-Only Access ----- # If you want a dashboard or external system to read aggregated data. user dashboard topic read parking/analytics/# # ===========================
However a better solution is to use the pattern option:
pattern write parking/sensors/zone1/%u/#
pattern read parking/commands/zone1/%u/#
pattern read parking/alerts/disconnected/%u
An alternative is to use the Pattern option with the sensor Id. This is my preferred approach if user name authentication isn’t going to be used.
pattern write parking/sensors/zone1/%c/#
pattern read parking/commands/zone1/%c/#
pattern read parking/alerts/disconnected/%c
mosquitto conf file addition.
allow_anonymous true acl_file /etc/mosquitto/mosquitto.acl
Note: I have used the standard location for the acl file on Linux in the example above. However in practise, for testing, I always place the files in my home folder and the example files you can download will use my local path.
Authentication
As an extra level of security you can also use user name and password authentication.
This requires creating a passwords file and forcing authentication in the mosquitto.conf file.
allow_anonymous false acl_file /etc/mosquitto/mosquitto.acl password_file /etc/mosquitto/passwd
Although most texts will recommend a unique user name and password for each sensor such a scenario is difficult to administer.
If you are using user names as part of the acl restrictions then a unique user name for each sensor is necessary but a unique password isn’t.
If you use the sensor ID for ACL restrictions (recommended) then all sensors can use the same user name and password.
Because the data isn’t really confidential I would not implement user name authentication in this scenario.
Encryption (SSL or End to End)
In our current implantation we are only sending non sensitive data and so there is no need to encrypt the data.
If our messages contained personal data like vehicle registration plates, or billing data then we would need to use some form of encryption.
If you use SSL then you must implement it on each link.
🔴 Problem: If data is only protected with SSL/TLS (which secures data in transit but not at rest), the broker can still see and store unencrypted license plates and payment data. If the broker is compromised, attackers could steal sensitive information.
If data is to be stored then end to end Encryption is the preferred choice.
Key Benefits of E2EE
✅ Even if the MQTT broker is hacked, data remains protected.
✅ Prevents unauthorized users from accessing sensitive parking and payment data.
✅ Ensures only intended recipients (backend, app) can decrypt messages.
✅ Complies with privacy regulations (GDPR, PCI-DSS for payments).
Data Frequency
A 5 minute send cycle would be often enough as changes are always sent immediately.
Questions
Q1- What would be the occupancy status if the sensor was detected to be offline?
Q2- If anonymous access is allowed and there is no password file do you need to send a password with the user name?
Workbook and Scripts
I will be making test python scripts, ACL files and mosquitto conf files available soon .
Answers
A1- unknown
A2 – no –
The follow table shows how the anonymous access setting and the password file settings affect client access.
Anonymous access | Password file Specified | Access Restricted |
True | No | No |
True | Yes | Yes See Note 1 |
False | No | Yes -see Note 2 |
False | Yes | Yes |
Note1: If a password file is specified then if the client sends a username/password then it must be valid otherwise an authentication error is returned.
If it doesn’t send one then none is required and a normal connection results.
Note 2: The client must send a User name and password, but it is not checked. If the client doesn’t send a user name/password then an authentication error code is generated.
Taken from Mosquitto Username and Password Authentication -Configuration and Testing
Questions?
Do you have any questions? Please use the comments form to ask
References:
- Mosquitto ACL -Configuring and Testing MQTT Topic Restrictions
- Configure a Mosquitto Bridge With SSL Encryption