2368 lines
41 KiB
Markdown
2368 lines
41 KiB
Markdown
# MQTT Management Platform
|
||
|
||
## Service Specification
|
||
|
||
**Status:** Initial specification, revised 2026-09-15 (MVP split into three releases)
|
||
**Target deployment:** Docker Compose / Portainer Stack
|
||
**Primary broker:** Eclipse Mosquitto 2.1.x
|
||
**Architecture:** Mosquitto + custom backend + custom frontend + PostgreSQL
|
||
|
||
---
|
||
|
||
# 1. Purpose
|
||
|
||
The purpose of the platform is to provide a centrally managed MQTT broker environment based on Eclipse Mosquitto together with a web-based administration interface.
|
||
|
||
The platform shall provide administrators with a controlled interface for:
|
||
|
||
* managing the MQTT broker;
|
||
* configuring listeners and broker behaviour;
|
||
* managing MQTT client authentication;
|
||
* managing MQTT client authorization and ACLs;
|
||
* generating and managing certificates;
|
||
* configuring TLS and mutual TLS;
|
||
* managing application administrators and operators;
|
||
* monitoring broker state;
|
||
* testing MQTT connectivity and permissions;
|
||
* auditing configuration and security changes;
|
||
* versioning and rolling back broker configuration;
|
||
* backing up and restoring configuration.
|
||
|
||
The management interface shall remove the normal requirement to directly edit Mosquitto configuration files, ACL files or certificate files on the host.
|
||
|
||
The system shall nevertheless generate standards-compliant Mosquitto configuration and retain the ability for an administrator to inspect the actual configuration generated by the platform.
|
||
|
||
---
|
||
|
||
# 2. Design principles
|
||
|
||
The platform shall follow the following design principles.
|
||
|
||
## 2.1 Separation of identities
|
||
|
||
Two distinct identity domains shall exist.
|
||
|
||
### Management identities
|
||
|
||
These are users of the web management platform.
|
||
|
||
Examples:
|
||
|
||
* Administrator
|
||
* MQTT administrator
|
||
* Certificate administrator
|
||
* Operator
|
||
* Auditor
|
||
|
||
These users authenticate against the backend API.
|
||
|
||
### MQTT identities
|
||
|
||
These are devices, applications, services or people connecting to Mosquitto.
|
||
|
||
Examples:
|
||
|
||
* PLC gateway
|
||
* IoT sensor
|
||
* SCADA application
|
||
* historian
|
||
* Grafana collector
|
||
* integration application
|
||
|
||
MQTT identities shall be managed separately from management users.
|
||
|
||
---
|
||
|
||
# 3. Proposed technology stack
|
||
|
||
## 3.1 Mosquitto
|
||
|
||
Use:
|
||
|
||
`eclipse-mosquitto:2.1.2-alpine`
|
||
|
||
or an explicitly pinned later 2.1.x release after verification.
|
||
|
||
The Docker image version shall always be pinned in production and shall not use `latest`.
|
||
|
||
Mosquitto shall provide:
|
||
|
||
* MQTT 5
|
||
* MQTT 3.1.1
|
||
* MQTT 3.1 where required
|
||
* TLS
|
||
* mutual TLS
|
||
* persistence
|
||
* retained messages
|
||
* Dynamic Security plugin
|
||
* `$SYS` telemetry
|
||
* optional WebSockets
|
||
* bridges
|
||
* broker control API where required
|
||
|
||
Mosquitto 2.1.2 is currently an official supported Docker tag.
|
||
|
||
---
|
||
|
||
## 3.2 Backend
|
||
|
||
Recommended implementation:
|
||
|
||
**Python 3.13 + FastAPI**
|
||
|
||
Supporting libraries should include:
|
||
|
||
* SQLAlchemy
|
||
* Alembic
|
||
* psycopg
|
||
* Pydantic
|
||
* cryptography
|
||
* Argon2id password hashing
|
||
* an MQTT 5 capable Python client
|
||
* structured logging
|
||
|
||
The backend shall expose a versioned REST API:
|
||
|
||
`/api/v1/...`
|
||
|
||
OpenAPI documentation shall automatically be generated.
|
||
|
||
---
|
||
|
||
## 3.3 Frontend
|
||
|
||
Recommended implementation:
|
||
|
||
**React + TypeScript**
|
||
|
||
Suggested tooling:
|
||
|
||
* Vite
|
||
* React Router
|
||
* TanStack Query
|
||
* component library suitable for administration interfaces
|
||
|
||
The frontend shall contain no privileged credentials.
|
||
|
||
It shall communicate exclusively with the backend REST API.
|
||
|
||
The frontend shall not directly modify Mosquitto configuration, Dynamic Security configuration or certificate files.
|
||
|
||
---
|
||
|
||
# 4. Docker architecture
|
||
|
||
The initial stack shall contain the following services.
|
||
|
||
```text
|
||
HTTPS
|
||
│
|
||
▼
|
||
┌─────────────────┐
|
||
│ Frontend │
|
||
│ React / nginx │
|
||
└────────┬────────┘
|
||
│
|
||
REST API
|
||
│
|
||
▼
|
||
┌─────────────────┐
|
||
│ Backend │
|
||
│ FastAPI │
|
||
└───┬────┬────┬──┘
|
||
│ │ │
|
||
│ │ └──────────────┐
|
||
│ │ │
|
||
│ ▼ ▼
|
||
│ PostgreSQL Broker Control
|
||
│ / config agent
|
||
│
|
||
▼
|
||
MQTT administration
|
||
│
|
||
▼
|
||
┌───────────────┐
|
||
│ Mosquitto │
|
||
│ MQTT Broker │
|
||
└───────────────┘
|
||
```
|
||
|
||
Required services:
|
||
|
||
```text
|
||
mqtt-frontend
|
||
mqtt-backend
|
||
mqtt-db
|
||
mosquitto
|
||
mosquitto-control
|
||
```
|
||
|
||
Optional future services:
|
||
|
||
```text
|
||
reverse-proxy
|
||
prometheus
|
||
grafana
|
||
loki
|
||
postgres-backup
|
||
```
|
||
|
||
---
|
||
|
||
# 5. Docker networks
|
||
|
||
At minimum two networks shall exist.
|
||
|
||
## 5.1 frontend-net
|
||
|
||
Contains:
|
||
|
||
* frontend
|
||
* backend
|
||
|
||
## 5.2 backend-net
|
||
|
||
Contains:
|
||
|
||
* backend
|
||
* PostgreSQL
|
||
* Mosquitto management interface
|
||
* Mosquitto control service
|
||
|
||
PostgreSQL shall not expose its port to the host by default.
|
||
|
||
The Mosquitto management/control interface shall not be externally accessible.
|
||
|
||
The normal MQTT listener may be exposed externally.
|
||
|
||
Example:
|
||
|
||
```text
|
||
8883/tcp MQTT TLS
|
||
1883/tcp optional MQTT plaintext
|
||
9001/tcp optional MQTT WebSocket
|
||
```
|
||
|
||
Plaintext port 1883 should be disabled by default in production.
|
||
|
||
---
|
||
|
||
# 6. Persistent storage
|
||
|
||
Separate Docker volumes shall be used.
|
||
|
||
```text
|
||
mqtt_db_data
|
||
mosquitto_data
|
||
mosquitto_config
|
||
mosquitto_certs
|
||
mosquitto_logs
|
||
mqtt_backend_data
|
||
```
|
||
|
||
The following information shall persist across container restarts:
|
||
|
||
* PostgreSQL database;
|
||
* Mosquitto persistence database;
|
||
* active Mosquitto configuration;
|
||
* Dynamic Security configuration;
|
||
* CA certificates;
|
||
* server certificates;
|
||
* encrypted private keys where applicable;
|
||
* CRLs;
|
||
* configuration revisions;
|
||
* audit information.
|
||
|
||
---
|
||
|
||
# 7. Environment configuration
|
||
|
||
A `.env` file may be supported for development.
|
||
|
||
Production installations should support Docker secrets for sensitive values.
|
||
|
||
Example configuration:
|
||
|
||
```env
|
||
APP_NAME=MQTT Management
|
||
APP_ENV=production
|
||
|
||
ADMIN_INITIAL_USERNAME=admin
|
||
ADMIN_INITIAL_PASSWORD=change-me
|
||
|
||
DATABASE_NAME=mqttadmin
|
||
DATABASE_USER=mqttadmin
|
||
DATABASE_PASSWORD=change-me
|
||
|
||
SESSION_SECRET=change-me
|
||
SECRET_ENCRYPTION_KEY=change-me
|
||
|
||
MOSQUITTO_HOST=mosquitto
|
||
MOSQUITTO_PORT=8883
|
||
|
||
MOSQUITTO_DYNSEC_USERNAME=admin
|
||
MOSQUITTO_DYNSEC_PASSWORD=change-me
|
||
|
||
DEFAULT_TLS_MIN_VERSION=TLSv1.2
|
||
DEFAULT_CERT_VALIDITY_DAYS=365
|
||
DEFAULT_CA_VALIDITY_DAYS=3650
|
||
```
|
||
|
||
Mosquitto 2.1 supports the `MOSQUITTO_DYNSEC_PASSWORD` environment variable for initial Dynamic Security administration setup.
|
||
|
||
## 7.1 Initial application administrator
|
||
|
||
`ADMIN_INITIAL_PASSWORD` shall only be used during initial backend bootstrap.
|
||
|
||
The backend shall:
|
||
|
||
1. determine whether an administrator already exists;
|
||
2. create the administrator only if none exists;
|
||
3. hash the password using Argon2id;
|
||
4. never persist the plaintext password;
|
||
5. require password change after first login.
|
||
|
||
Once initialization has completed, changing `ADMIN_INITIAL_PASSWORD` shall not automatically overwrite the administrator's password.
|
||
|
||
## 7.2 Frontend password configuration
|
||
|
||
No administrator password shall be compiled into the frontend.
|
||
|
||
The requirement for an environment-configured default administrator password therefore applies to the **management application as a whole**, with the backend consuming the environment variable.
|
||
|
||
Browser-visible frontend environment variables shall never contain:
|
||
|
||
* passwords;
|
||
* API secrets;
|
||
* private keys;
|
||
* signing secrets;
|
||
* database credentials;
|
||
* Dynamic Security credentials.
|
||
|
||
---
|
||
|
||
# 8. Management authentication
|
||
|
||
The frontend shall authenticate management users against the backend.
|
||
|
||
Recommended authentication mechanism:
|
||
|
||
```text
|
||
Browser
|
||
│
|
||
│ username/password
|
||
▼
|
||
Backend
|
||
│
|
||
├── validate credentials
|
||
├── create session
|
||
└── return secure session cookie
|
||
```
|
||
|
||
Sessions should use:
|
||
|
||
* Secure cookies;
|
||
* HttpOnly;
|
||
* SameSite;
|
||
* session expiration;
|
||
* server-side revocation.
|
||
|
||
Authentication tokens should not normally be stored in browser `localStorage`.
|
||
|
||
---
|
||
|
||
# 9. Management RBAC
|
||
|
||
Application RBAC shall be independent of MQTT ACL configuration.
|
||
|
||
Initial roles:
|
||
|
||
### Super Administrator
|
||
|
||
Full platform access.
|
||
|
||
### Broker Administrator
|
||
|
||
May:
|
||
|
||
* configure Mosquitto;
|
||
* manage listeners;
|
||
* manage MQTT clients;
|
||
* manage MQTT roles/groups/ACLs;
|
||
* apply configuration.
|
||
|
||
### PKI Administrator
|
||
|
||
May:
|
||
|
||
* manage CAs;
|
||
* generate certificates;
|
||
* sign CSRs;
|
||
* revoke certificates;
|
||
* generate CRLs.
|
||
|
||
### Operator
|
||
|
||
May:
|
||
|
||
* view broker status;
|
||
* inspect clients;
|
||
* inspect topics;
|
||
* perform permitted diagnostic operations.
|
||
|
||
### Auditor
|
||
|
||
Read-only access to:
|
||
|
||
* configuration;
|
||
* certificates;
|
||
* users;
|
||
* audit logs;
|
||
* configuration history.
|
||
|
||
The platform shall support creation of additional custom roles in a later release.
|
||
|
||
---
|
||
|
||
# 10. Mosquitto authentication and authorization
|
||
|
||
The preferred authorization mechanism shall be the **Mosquitto Dynamic Security plugin**.
|
||
|
||
Dynamic Security provides:
|
||
|
||
```text
|
||
Clients
|
||
│
|
||
├── Groups
|
||
│ │
|
||
│ └── Roles
|
||
│ │
|
||
│ └── ACL rules
|
||
│
|
||
└── Roles
|
||
│
|
||
└── ACL rules
|
||
```
|
||
|
||
Mosquitto supports dynamic clients, groups, roles and ACLs while the broker is running.
|
||
|
||
---
|
||
|
||
# 11. MQTT client management
|
||
|
||
The frontend shall provide a page named:
|
||
|
||
**Clients**
|
||
|
||
Each MQTT client shall support metadata including:
|
||
|
||
```text
|
||
Username
|
||
Client ID
|
||
Display name
|
||
Description
|
||
Enabled/disabled
|
||
Authentication method
|
||
Certificate identity
|
||
Groups
|
||
Direct roles
|
||
Tags
|
||
Owner
|
||
Purpose
|
||
Created timestamp
|
||
Modified timestamp
|
||
Last known connection
|
||
```
|
||
|
||
The user shall be able to:
|
||
|
||
* create a client;
|
||
* disable a client;
|
||
* enable a client;
|
||
* delete a client;
|
||
* reset a password;
|
||
* generate a random password;
|
||
* assign groups;
|
||
* assign roles;
|
||
* bind an expected client ID;
|
||
* issue a client certificate;
|
||
* revoke a client certificate.
|
||
|
||
Passwords shall never be retrievable after creation.
|
||
|
||
---
|
||
|
||
# 12. MQTT groups
|
||
|
||
The frontend shall provide a page named:
|
||
|
||
**Groups**
|
||
|
||
Example groups might be:
|
||
|
||
```text
|
||
SCADA
|
||
Sensors
|
||
Gateways
|
||
Historians
|
||
Grafana
|
||
Administrators
|
||
Site-A
|
||
Site-B
|
||
```
|
||
|
||
A group may have:
|
||
|
||
* name;
|
||
* display name;
|
||
* description;
|
||
* clients;
|
||
* roles;
|
||
* role priority.
|
||
|
||
---
|
||
|
||
# 13. MQTT roles
|
||
|
||
The frontend shall provide a page named:
|
||
|
||
**Roles**
|
||
|
||
Example:
|
||
|
||
```text
|
||
role: site-a-sensors
|
||
|
||
ALLOW publishClientSend
|
||
site/a/%u/telemetry/#
|
||
|
||
ALLOW subscribePattern
|
||
site/a/%u/config/#
|
||
|
||
ALLOW publishClientReceive
|
||
site/a/%u/config/#
|
||
```
|
||
|
||
The UI should present ACL rules in a table rather than requiring users to manually manipulate Mosquitto JSON.
|
||
|
||
Mosquitto Dynamic Security supports ACL types including publishing, receiving, subscribing and unsubscribing as well as `%u` username and `%c` client-ID substitutions.
|
||
|
||
---
|
||
|
||
# 14. ACL editor
|
||
|
||
The ACL editor shall support:
|
||
|
||
```text
|
||
ACL type
|
||
Topic filter
|
||
Allow / deny
|
||
Priority
|
||
Description
|
||
```
|
||
|
||
ACL types shall include:
|
||
|
||
```text
|
||
publishClientSend
|
||
publishClientReceive
|
||
subscribeLiteral
|
||
subscribePattern
|
||
unsubscribeLiteral
|
||
unsubscribePattern
|
||
```
|
||
|
||
The UI shall show a human-readable interpretation.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Client:
|
||
pumpstation-042
|
||
|
||
Role:
|
||
pumpstation
|
||
|
||
ACL:
|
||
site/%u/telemetry/#
|
||
|
||
Resolved example:
|
||
site/pumpstation-042/telemetry/#
|
||
```
|
||
|
||
---
|
||
|
||
# 15. ACL simulator
|
||
|
||
A highly recommended feature is an **ACL simulator**.
|
||
|
||
The administrator shall be able to enter:
|
||
|
||
```text
|
||
Client
|
||
Client ID
|
||
Operation
|
||
Topic
|
||
```
|
||
|
||
Example:
|
||
|
||
```text
|
||
client: ps042
|
||
operation: publish
|
||
topic: vivab/ps042/status
|
||
```
|
||
|
||
The application shall evaluate the current role/group hierarchy and display:
|
||
|
||
```text
|
||
ALLOW
|
||
|
||
Matched through:
|
||
client ps042
|
||
→ group pumpstations
|
||
→ role telemetry-producer
|
||
→ ACL vivab/%u/status
|
||
```
|
||
|
||
or:
|
||
|
||
```text
|
||
DENY
|
||
|
||
No matching allow rule.
|
||
```
|
||
|
||
This would substantially reduce ACL configuration mistakes.
|
||
|
||
---
|
||
|
||
# 16. Certificate management
|
||
|
||
The frontend shall provide a complete PKI management area.
|
||
|
||
The UI triggers certificate operations while all private-key and signing operations are performed by the backend.
|
||
|
||
Pages:
|
||
|
||
```text
|
||
Certificate Authorities
|
||
Server Certificates
|
||
Client Certificates
|
||
Certificate Requests
|
||
Revocations
|
||
Certificate Policies
|
||
```
|
||
|
||
---
|
||
|
||
# 17. Certificate authority
|
||
|
||
The system shall support creation of an internal CA.
|
||
|
||
At minimum:
|
||
|
||
```text
|
||
CA name
|
||
Common Name
|
||
Organization
|
||
Organizational Unit
|
||
Country
|
||
Validity
|
||
Key algorithm
|
||
Key length
|
||
Creation date
|
||
Expiration date
|
||
Status
|
||
```
|
||
|
||
Supported key types should initially include:
|
||
|
||
```text
|
||
RSA 3072
|
||
RSA 4096
|
||
ECDSA P-256
|
||
ECDSA P-384
|
||
```
|
||
|
||
---
|
||
|
||
# 18. Recommended CA hierarchy
|
||
|
||
Production use should support:
|
||
|
||
```text
|
||
Offline Root CA
|
||
│
|
||
▼
|
||
MQTT Intermediate CA
|
||
│
|
||
├── Broker certificate
|
||
├── Client certificate
|
||
├── Client certificate
|
||
└── Client certificate
|
||
```
|
||
|
||
The system may generate the root CA during initial setup, but should allow the root key to subsequently be exported and removed from the online platform.
|
||
|
||
The backend should preferably keep only the intermediate signing CA online.
|
||
|
||
---
|
||
|
||
# 19. Server certificate generation
|
||
|
||
The UI shall allow an administrator to specify:
|
||
|
||
```text
|
||
Common Name
|
||
DNS SANs
|
||
IP SANs
|
||
Validity
|
||
Key algorithm
|
||
```
|
||
|
||
Example:
|
||
|
||
```text
|
||
CN = mqtt.example.local
|
||
|
||
SAN:
|
||
mqtt.example.local
|
||
mqtt
|
||
10.20.30.40
|
||
```
|
||
|
||
The generated certificate shall contain the appropriate `serverAuth` extended key usage.
|
||
|
||
---
|
||
|
||
# 20. Client certificate generation
|
||
|
||
The frontend shall support two modes.
|
||
|
||
## Managed key generation
|
||
|
||
Backend generates:
|
||
|
||
```text
|
||
client.key
|
||
client.crt
|
||
ca.crt
|
||
```
|
||
|
||
The files can be delivered as:
|
||
|
||
```text
|
||
ZIP
|
||
PEM
|
||
PKCS#12/PFX
|
||
```
|
||
|
||
The generated bundle should be available for one-time download.
|
||
|
||
## CSR mode
|
||
|
||
Preferred for higher security.
|
||
|
||
The client generates its own private key and submits a CSR.
|
||
|
||
The frontend allows the administrator to:
|
||
|
||
1. upload or paste CSR;
|
||
2. inspect subject and SANs;
|
||
3. approve signing;
|
||
4. issue certificate;
|
||
5. download signed certificate and CA chain.
|
||
|
||
The private key then never enters the management platform.
|
||
|
||
---
|
||
|
||
# 21. Certificate inventory
|
||
|
||
Each certificate shall be tracked with:
|
||
|
||
```text
|
||
Serial number
|
||
Subject
|
||
Issuer
|
||
Common Name
|
||
SAN
|
||
Certificate type
|
||
Associated MQTT client
|
||
Issued date
|
||
Expiration date
|
||
Status
|
||
Fingerprint
|
||
Revocation date
|
||
Revocation reason
|
||
```
|
||
|
||
---
|
||
|
||
# 22. Certificate revocation
|
||
|
||
The platform shall support:
|
||
|
||
* certificate revocation;
|
||
* CRL generation;
|
||
* CRL renewal;
|
||
* publication of active CRL to Mosquitto;
|
||
* immediate application of changed CRL.
|
||
|
||
Mosquitto can be configured with a PEM encoded CRL using `crlfile` when client certificates are required.
|
||
|
||
---
|
||
|
||
# 23. Certificate expiry monitoring
|
||
|
||
Dashboard warnings shall be generated at configurable intervals.
|
||
|
||
Example:
|
||
|
||
```text
|
||
90 days
|
||
60 days
|
||
30 days
|
||
14 days
|
||
7 days
|
||
Expired
|
||
```
|
||
|
||
Future support should allow notification through:
|
||
|
||
```text
|
||
SMTP
|
||
Webhook
|
||
Teams
|
||
Slack
|
||
MQTT
|
||
```
|
||
|
||
---
|
||
|
||
# 24. Mutual TLS
|
||
|
||
The platform shall support listeners where:
|
||
|
||
```text
|
||
require_certificate true
|
||
```
|
||
|
||
Optional identity mapping:
|
||
|
||
```text
|
||
use_identity_as_username true
|
||
```
|
||
|
||
Mosquitto can use the certificate CN as the MQTT username when client certificates are required.
|
||
|
||
This enables an architecture such as:
|
||
|
||
```text
|
||
Certificate CN:
|
||
ps042
|
||
|
||
│
|
||
▼
|
||
|
||
MQTT identity:
|
||
ps042
|
||
|
||
│
|
||
▼
|
||
|
||
Dynamic Security:
|
||
client ps042
|
||
|
||
│
|
||
▼
|
||
|
||
Role/ACL evaluation
|
||
```
|
||
|
||
This combination shall be explicitly integration-tested as part of the implementation.
|
||
|
||
---
|
||
|
||
# 25. Mosquitto configuration management
|
||
|
||
The platform shall not directly overwrite the active configuration when an administrator edits a setting.
|
||
|
||
Instead:
|
||
|
||
```text
|
||
Edit
|
||
↓
|
||
Draft configuration
|
||
↓
|
||
Validate
|
||
↓
|
||
Show diff
|
||
↓
|
||
Approve
|
||
↓
|
||
Create revision
|
||
↓
|
||
Deploy
|
||
↓
|
||
Reload/restart
|
||
↓
|
||
Health check
|
||
```
|
||
|
||
---
|
||
|
||
# 26. Configuration revisions
|
||
|
||
Each broker configuration change shall generate a revision.
|
||
|
||
Store:
|
||
|
||
```text
|
||
Revision ID
|
||
Timestamp
|
||
User
|
||
Reason/comment
|
||
Previous revision
|
||
Generated mosquitto.conf
|
||
Change diff
|
||
Validation result
|
||
Deployment result
|
||
```
|
||
|
||
The administrator shall be able to view:
|
||
|
||
```text
|
||
Revision 34 → Revision 35
|
||
|
||
- max_connections 1000
|
||
+ max_connections 2000
|
||
|
||
- log_type warning
|
||
+ log_type notice
|
||
```
|
||
|
||
---
|
||
|
||
# 27. Configuration validation
|
||
|
||
Before deployment, the generated Mosquitto configuration shall be tested.
|
||
|
||
Mosquitto 2.1 provides:
|
||
|
||
```text
|
||
mosquitto -c mosquitto.conf --test-config
|
||
```
|
||
|
||
The command exits successfully when the configuration is valid without starting the broker.
|
||
|
||
A configuration failing validation shall never become active.
|
||
|
||
---
|
||
|
||
# 28. Configuration reload
|
||
|
||
Where supported, changes shall be applied using a configuration reload.
|
||
|
||
Mosquitto 2.1 provides:
|
||
|
||
```text
|
||
mosquitto_signal config-reload
|
||
```
|
||
|
||
or equivalent `SIGHUP` behaviour.
|
||
|
||
The frontend shall distinguish:
|
||
|
||
```text
|
||
No reload required
|
||
Reload required
|
||
Broker restart required
|
||
```
|
||
|
||
because not every Mosquitto option can be dynamically reloaded.
|
||
|
||
---
|
||
|
||
# 29. Broker control service
|
||
|
||
A small internal `mosquitto-control` service is recommended.
|
||
|
||
Its responsibilities shall be limited to:
|
||
|
||
```text
|
||
validate staged configuration
|
||
activate configuration revision
|
||
signal config reload
|
||
signal log rotation
|
||
restart broker where explicitly supported
|
||
check broker process state
|
||
```
|
||
|
||
The normal backend shall call this service through an isolated Docker network.
|
||
|
||
The Docker socket:
|
||
|
||
```text
|
||
/var/run/docker.sock
|
||
```
|
||
|
||
shall **not** be mounted into the frontend or backend.
|
||
|
||
This avoids giving the web application unrestricted control over the Docker host.
|
||
|
||
---
|
||
|
||
# 30. Listener management
|
||
|
||
The frontend shall support graphical configuration of Mosquitto listeners.
|
||
|
||
Fields include:
|
||
|
||
```text
|
||
Port
|
||
Protocol
|
||
Bind address
|
||
IPv4/IPv6
|
||
TLS enabled
|
||
Certificate
|
||
CA
|
||
Client certificates required
|
||
Minimum TLS version
|
||
Authentication mode
|
||
WebSockets
|
||
Maximum connections
|
||
Anonymous access
|
||
```
|
||
|
||
Example:
|
||
|
||
```text
|
||
Listener: Production MQTT
|
||
|
||
Port: 8883
|
||
Protocol: MQTT
|
||
TLS: enabled
|
||
Minimum TLS: TLS 1.2
|
||
Client certificate: required
|
||
Anonymous: false
|
||
```
|
||
|
||
---
|
||
|
||
# 31. Broker settings
|
||
|
||
The UI should support commonly required settings including:
|
||
|
||
```text
|
||
persistence
|
||
autosave_interval
|
||
global_max_clients
|
||
max_connections
|
||
max_queued_messages
|
||
max_queued_bytes
|
||
message_size_limit
|
||
max_inflight_messages
|
||
keepalive behaviour
|
||
connection logging
|
||
log levels
|
||
retain support
|
||
WebSockets
|
||
```
|
||
|
||
Advanced settings may initially be exposed through an expert configuration editor.
|
||
|
||
---
|
||
|
||
# 32. Safe configuration editor
|
||
|
||
The UI shall have two modes.
|
||
|
||
## Basic mode
|
||
|
||
Structured forms.
|
||
|
||
## Advanced mode
|
||
|
||
Show generated:
|
||
|
||
`mosquitto.conf`
|
||
|
||
The advanced editor shall not directly replace the active file.
|
||
|
||
Changes still undergo:
|
||
|
||
```text
|
||
validation
|
||
revision creation
|
||
diff
|
||
approval
|
||
deployment
|
||
```
|
||
|
||
---
|
||
|
||
# 33. Broker dashboard
|
||
|
||
The landing page should show:
|
||
|
||
```text
|
||
Broker status
|
||
Broker version
|
||
Uptime
|
||
|
||
Connected clients
|
||
Stored sessions
|
||
Subscriptions
|
||
Retained messages
|
||
|
||
Messages received/sec
|
||
Messages sent/sec
|
||
|
||
Bytes received/sec
|
||
Bytes sent/sec
|
||
|
||
Dropped messages
|
||
Publish failures
|
||
|
||
Certificates expiring
|
||
Disabled clients
|
||
Recent authentication failures
|
||
|
||
Current config revision
|
||
Last backup
|
||
```
|
||
|
||
Much of the runtime information can be collected from Mosquitto `$SYS/#`.
|
||
|
||
---
|
||
|
||
# 34. Connected-client view
|
||
|
||
Where information is available, display:
|
||
|
||
```text
|
||
Client ID
|
||
Username
|
||
Source IP
|
||
Protocol version
|
||
Connected since
|
||
Keepalive
|
||
Session state
|
||
Subscriptions
|
||
Authentication mechanism
|
||
Certificate
|
||
```
|
||
|
||
Future versions may use a Mosquitto plugin if more detailed connection information is required than `$SYS` exposes.
|
||
|
||
---
|
||
|
||
# 35. Topic explorer
|
||
|
||
A useful management tool shall be provided.
|
||
|
||
The administrator can:
|
||
|
||
```text
|
||
subscribe to a topic filter
|
||
inspect messages
|
||
publish test messages
|
||
select QoS
|
||
set retained flag
|
||
inspect MQTT 5 properties
|
||
```
|
||
|
||
## 35.1 Consolidated topic view
|
||
|
||
The live message view shall be organized as ONE ROW PER KNOWN TOPIC
|
||
(rather than one row per received message), so an active topic tree is
|
||
browsable at a glance. For each row:
|
||
|
||
* on receiving a new message, the row shall HIGHLIGHT THE DIFFERENCES
|
||
between the new message and the previously known message for that
|
||
topic (payload, QoS, retain flag and MQTT 5 properties that changed)
|
||
* the row shall GLOW briefly when a new message arrives, so the user
|
||
notices activity without watching every row
|
||
|
||
The full KNOWN HISTORY of each topic shall be browsable: selecting a
|
||
topic row opens its message history (most recent first), from which any
|
||
entry can be inspected in detail (payload as text/hex, QoS, retain
|
||
flag, MQTT 5 properties, arrival time).
|
||
|
||
Example:
|
||
|
||
```text
|
||
Subscribe:
|
||
vivab/+/telemetry/#
|
||
|
||
Publish:
|
||
vivab/test/command
|
||
```
|
||
|
||
Access to this feature shall be restricted through management RBAC.
|
||
|
||
All publishes through the test console shall be audited.
|
||
|
||
---
|
||
|
||
# 36. Retained-message management
|
||
|
||
The frontend should support:
|
||
|
||
```text
|
||
list known retained topics where feasible
|
||
inspect retained payload
|
||
clear retained message
|
||
publish replacement
|
||
```
|
||
|
||
Destructive actions shall require explicit confirmation.
|
||
|
||
---
|
||
|
||
# 37. Bridge management
|
||
|
||
Mosquitto supports connections between brokers through bridges.
|
||
|
||
The platform should therefore support configuration of:
|
||
|
||
```text
|
||
Bridge name
|
||
Remote broker
|
||
Port
|
||
TLS
|
||
CA
|
||
Client certificate
|
||
Username
|
||
Password
|
||
Remote topics
|
||
Local topics
|
||
Direction
|
||
QoS
|
||
Clean start
|
||
Reconnect interval
|
||
```
|
||
|
||
This is particularly useful for distributed OT environments.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Pump station broker
|
||
│
|
||
│ MQTT bridge
|
||
▼
|
||
Central MQTT broker
|
||
```
|
||
|
||
---
|
||
|
||
# 38. Audit log
|
||
|
||
All privileged actions shall be audited.
|
||
|
||
Each audit event shall contain:
|
||
|
||
```text
|
||
Timestamp
|
||
User
|
||
Source IP
|
||
Action
|
||
Object type
|
||
Object identifier
|
||
Old value
|
||
New value
|
||
Result
|
||
Correlation ID
|
||
```
|
||
|
||
Examples:
|
||
|
||
```text
|
||
CLIENT_CREATED
|
||
CLIENT_DISABLED
|
||
ACL_CHANGED
|
||
CERTIFICATE_ISSUED
|
||
CERTIFICATE_REVOKED
|
||
BROKER_CONFIG_CHANGED
|
||
BROKER_CONFIG_DEPLOYED
|
||
BROKER_RESTARTED
|
||
USER_CREATED
|
||
ROLE_CHANGED
|
||
LOGIN_FAILED
|
||
BACKUP_CREATED
|
||
RESTORE_PERFORMED
|
||
```
|
||
|
||
Audit records should be append-only from the application's perspective.
|
||
|
||
---
|
||
|
||
# 39. Application database
|
||
|
||
Recommended database:
|
||
|
||
**PostgreSQL**
|
||
|
||
Initial logical entities:
|
||
|
||
```text
|
||
users
|
||
roles
|
||
permissions
|
||
user_roles
|
||
|
||
broker_settings
|
||
broker_config_revisions
|
||
|
||
certificate_authorities
|
||
certificates
|
||
certificate_revocations
|
||
|
||
mqtt_client_metadata
|
||
|
||
audit_events
|
||
|
||
system_settings
|
||
|
||
backup_records
|
||
```
|
||
|
||
Dynamic Security clients/groups/roles shall remain managed by Mosquitto.
|
||
|
||
The application database stores additional metadata and synchronization state.
|
||
|
||
---
|
||
|
||
# 40. Source-of-truth model
|
||
|
||
The system shall have clear ownership rules.
|
||
|
||
```text
|
||
Management users
|
||
→ PostgreSQL
|
||
|
||
Management RBAC
|
||
→ PostgreSQL
|
||
|
||
MQTT authentication
|
||
→ Mosquitto Dynamic Security
|
||
|
||
MQTT ACL
|
||
→ Mosquitto Dynamic Security
|
||
|
||
MQTT client metadata
|
||
→ PostgreSQL
|
||
|
||
Broker configuration
|
||
→ PostgreSQL revision + generated files
|
||
|
||
Certificates
|
||
→ backend PKI store
|
||
|
||
Mosquitto runtime state
|
||
→ Mosquitto
|
||
```
|
||
|
||
The backend shall reconcile its expected Dynamic Security configuration with Mosquitto and report discrepancies.
|
||
|
||
---
|
||
|
||
# 41. Backend API
|
||
|
||
Minimum API groups:
|
||
|
||
```text
|
||
/api/v1/auth
|
||
/api/v1/users
|
||
/api/v1/roles
|
||
|
||
/api/v1/broker
|
||
/api/v1/broker/config
|
||
/api/v1/broker/revisions
|
||
/api/v1/broker/status
|
||
|
||
/api/v1/mqtt/clients
|
||
/api/v1/mqtt/groups
|
||
/api/v1/mqtt/roles
|
||
/api/v1/mqtt/acls
|
||
|
||
/api/v1/pki/ca
|
||
/api/v1/pki/certificates
|
||
/api/v1/pki/csr
|
||
/api/v1/pki/crl
|
||
|
||
/api/v1/topics
|
||
|
||
/api/v1/audit
|
||
|
||
/api/v1/backups
|
||
/api/v1/system
|
||
```
|
||
|
||
---
|
||
|
||
# 42. API conventions
|
||
|
||
The REST API shall:
|
||
|
||
* use JSON;
|
||
* use ISO 8601 timestamps;
|
||
* use UUID identifiers;
|
||
* provide consistent error objects;
|
||
* provide pagination;
|
||
* provide filtering;
|
||
* provide sorting;
|
||
* provide request correlation IDs;
|
||
* automatically generate OpenAPI documentation.
|
||
|
||
Example error:
|
||
|
||
```json
|
||
{
|
||
"code": "ACL_CONFLICT",
|
||
"message": "The ACL conflicts with an existing higher priority deny rule.",
|
||
"correlation_id": "..."
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# 43. Secret storage
|
||
|
||
Passwords shall use non-reversible hashing where authentication only requires validation.
|
||
|
||
Recommended:
|
||
|
||
```text
|
||
Argon2id
|
||
```
|
||
|
||
Secrets that must later be retrieved shall be encrypted.
|
||
|
||
Examples:
|
||
|
||
```text
|
||
CA private keys
|
||
bridge passwords
|
||
service credentials
|
||
PKCS#12 passwords
|
||
```
|
||
|
||
Use authenticated encryption such as:
|
||
|
||
```text
|
||
AES-256-GCM
|
||
```
|
||
|
||
The encryption master key shall be provided externally through:
|
||
|
||
```text
|
||
Docker secret
|
||
|
||
or
|
||
|
||
environment variable for development
|
||
```
|
||
|
||
The master key shall never be stored in PostgreSQL.
|
||
|
||
---
|
||
|
||
# 44. Private-key handling
|
||
|
||
Certificate private keys shall be handled according to their purpose.
|
||
|
||
### Server private key
|
||
|
||
May be stored encrypted because Mosquitto requires continued access.
|
||
|
||
### Intermediate CA private key
|
||
|
||
May be stored encrypted.
|
||
|
||
### Root CA private key
|
||
|
||
Preferably export and remove after creation.
|
||
|
||
### Client private key
|
||
|
||
Prefer CSR-based issuance.
|
||
|
||
If generated by the system:
|
||
|
||
* encrypt at rest;
|
||
* permit one-time download;
|
||
* optionally delete after download.
|
||
|
||
---
|
||
|
||
# 45. Backup and restore
|
||
|
||
The frontend shall provide backup administration.
|
||
|
||
A logical backup shall include:
|
||
|
||
```text
|
||
PostgreSQL database
|
||
Mosquitto configuration
|
||
Dynamic Security configuration
|
||
certificate database
|
||
encrypted CA/server keys
|
||
CRL
|
||
application configuration
|
||
```
|
||
|
||
Mosquitto persistence data may optionally be included depending on the selected backup mode.
|
||
|
||
Backup files shall be encrypted.
|
||
|
||
The UI shall support:
|
||
|
||
```text
|
||
Create backup
|
||
Download backup
|
||
Verify backup
|
||
Restore backup
|
||
```
|
||
|
||
Restore shall require elevated privileges.
|
||
|
||
---
|
||
|
||
# 46. Health checks
|
||
|
||
Each container shall provide a health check.
|
||
|
||
Backend health:
|
||
|
||
```text
|
||
/health/live
|
||
/health/ready
|
||
```
|
||
|
||
Readiness should verify:
|
||
|
||
```text
|
||
database
|
||
Mosquitto management connection
|
||
certificate storage
|
||
configuration storage
|
||
```
|
||
|
||
The dashboard shall distinguish:
|
||
|
||
```text
|
||
Frontend healthy
|
||
Backend healthy
|
||
Database healthy
|
||
Broker healthy
|
||
Management channel healthy
|
||
```
|
||
|
||
---
|
||
|
||
# 47. Logging
|
||
|
||
The platform shall use structured logs.
|
||
|
||
Recommended format:
|
||
|
||
```json
|
||
{
|
||
"timestamp": "...",
|
||
"level": "INFO",
|
||
"service": "mqtt-backend",
|
||
"event": "certificate_issued",
|
||
"correlation_id": "...",
|
||
"user": "admin"
|
||
}
|
||
```
|
||
|
||
Passwords, private keys and authentication tokens shall never be logged.
|
||
|
||
---
|
||
|
||
# 48. Configuration drift detection
|
||
|
||
A highly recommended feature is configuration drift detection.
|
||
|
||
The system shall periodically compare:
|
||
|
||
```text
|
||
expected configuration
|
||
vs
|
||
active Mosquitto configuration
|
||
```
|
||
|
||
and report:
|
||
|
||
```text
|
||
IN SYNC
|
||
DRIFT DETECTED
|
||
UNKNOWN
|
||
```
|
||
|
||
The same principle should apply to Dynamic Security configuration.
|
||
|
||
This is particularly useful where administrators still have shell access to the host.
|
||
|
||
---
|
||
|
||
# 49. Change approval
|
||
|
||
A later version should optionally support a four-eyes workflow.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Administrator A
|
||
│
|
||
▼
|
||
Proposes ACL change
|
||
│
|
||
▼
|
||
Administrator B
|
||
│
|
||
▼
|
||
Approves
|
||
│
|
||
▼
|
||
Backend applies change
|
||
```
|
||
|
||
This should be configurable rather than mandatory.
|
||
|
||
It is especially useful in OT environments where an ACL or listener change can affect production communications.
|
||
|
||
---
|
||
|
||
# 50. Client provisioning workflow
|
||
|
||
The frontend should provide a provisioning wizard.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Create client
|
||
↓
|
||
Select authentication
|
||
↓
|
||
Generate credentials/certificate
|
||
↓
|
||
Select group
|
||
↓
|
||
Assign roles
|
||
↓
|
||
Evaluate ACL
|
||
↓
|
||
Test credentials
|
||
↓
|
||
Download package
|
||
```
|
||
|
||
The generated package could contain:
|
||
|
||
```text
|
||
ca.crt
|
||
client.crt
|
||
client.key
|
||
README.txt
|
||
connection.json
|
||
mosquitto_pub-example.txt
|
||
mosquitto_sub-example.txt
|
||
```
|
||
|
||
---
|
||
|
||
# 51. Connection profile export
|
||
|
||
A very useful feature would be generation of ready-to-use client configuration.
|
||
|
||
Example:
|
||
|
||
```json
|
||
{
|
||
"host": "mqtt.example.local",
|
||
"port": 8883,
|
||
"clientId": "PS042",
|
||
"username": "PS042",
|
||
"tls": true,
|
||
"ca": "ca.crt",
|
||
"certificate": "client.crt",
|
||
"privateKey": "client.key"
|
||
}
|
||
```
|
||
|
||
The frontend may generate example configuration for:
|
||
|
||
```text
|
||
mosquitto_pub/sub
|
||
Python
|
||
Node.js
|
||
Node-RED
|
||
Ignition
|
||
Grafana
|
||
generic MQTT clients
|
||
```
|
||
|
||
---
|
||
|
||
# 52. Test connection
|
||
|
||
After creating a client, the administrator should be able to perform:
|
||
|
||
```text
|
||
Authentication test
|
||
TLS test
|
||
Publish test
|
||
Subscribe test
|
||
ACL test
|
||
```
|
||
|
||
Result:
|
||
|
||
```text
|
||
TLS handshake PASS
|
||
Certificate PASS
|
||
Authentication PASS
|
||
Publish telemetry PASS
|
||
Subscribe commands PASS
|
||
Forbidden topic DENIED — expected
|
||
```
|
||
|
||
This provides a useful commissioning function.
|
||
|
||
---
|
||
|
||
# 53. MQTT namespace documentation
|
||
|
||
The frontend should optionally contain a **Topic Namespace** registry.
|
||
|
||
Example:
|
||
|
||
```text
|
||
vivab/{site}/{device}/telemetry/{signal}
|
||
vivab/{site}/{device}/status
|
||
vivab/{site}/{device}/command/{command}
|
||
vivab/{site}/{device}/config/{parameter}
|
||
```
|
||
|
||
Administrators can document:
|
||
|
||
```text
|
||
topic pattern
|
||
purpose
|
||
payload schema
|
||
publisher
|
||
subscriber
|
||
QoS
|
||
retain behaviour
|
||
owner
|
||
```
|
||
|
||
This goes beyond native Mosquitto administration but would be extremely valuable as the MQTT environment grows.
|
||
|
||
---
|
||
|
||
# 54. Payload/schema registry – future feature
|
||
|
||
A later version could associate topic patterns with schemas.
|
||
|
||
Example:
|
||
|
||
```text
|
||
vivab/+/+/telemetry/level
|
||
```
|
||
|
||
Schema:
|
||
|
||
```json
|
||
{
|
||
"type": "object",
|
||
"properties": {
|
||
"value": {
|
||
"type": "number"
|
||
},
|
||
"unit": {
|
||
"const": "m"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
The test console could then validate messages against the expected schema.
|
||
|
||
---
|
||
|
||
# 55. Metrics
|
||
|
||
The backend shall collect broker metrics from `$SYS/#`.
|
||
|
||
Metrics should include:
|
||
|
||
```text
|
||
uptime
|
||
clients connected
|
||
clients disconnected
|
||
subscriptions
|
||
stored messages
|
||
retained messages
|
||
messages received
|
||
messages sent
|
||
bytes received
|
||
bytes sent
|
||
publish received
|
||
publish sent
|
||
dropped messages
|
||
load
|
||
```
|
||
|
||
Historical storage should initially be optional.
|
||
|
||
Prometheus support may later be added.
|
||
|
||
---
|
||
|
||
# 56. Alerts
|
||
|
||
The platform should eventually support configurable alerts such as:
|
||
|
||
```text
|
||
Broker unavailable
|
||
Client count unusually high
|
||
Certificate expiring
|
||
Certificate expired
|
||
Repeated authentication failures
|
||
Configuration drift detected
|
||
Backup failure
|
||
Bridge disconnected
|
||
Disk usage high
|
||
```
|
||
|
||
---
|
||
|
||
# 57. UI navigation
|
||
|
||
Recommended primary navigation:
|
||
|
||
```text
|
||
Dashboard
|
||
|
||
Broker
|
||
├── Status
|
||
├── Configuration
|
||
├── Listeners
|
||
├── Bridges
|
||
└── Revisions
|
||
|
||
MQTT Security
|
||
├── Clients
|
||
├── Groups
|
||
├── Roles
|
||
├── ACL Simulator
|
||
└── Authentication
|
||
|
||
Certificates
|
||
├── Authorities
|
||
├── Server Certificates
|
||
├── Client Certificates
|
||
├── CSRs
|
||
└── Revocations
|
||
|
||
Tools
|
||
├── Topic Explorer
|
||
├── Connection Test
|
||
└── Client Provisioning
|
||
|
||
Administration
|
||
├── Users
|
||
├── Roles
|
||
├── Audit Log
|
||
├── Backup
|
||
└── System
|
||
```
|
||
|
||
---
|
||
|
||
# 58. Security defaults
|
||
|
||
The default installation shall favour secure configuration.
|
||
|
||
Recommended defaults:
|
||
|
||
```text
|
||
allow_anonymous false
|
||
|
||
TLS required externally
|
||
|
||
Minimum TLS version TLS 1.2
|
||
|
||
Plain MQTT listener disabled
|
||
|
||
Default ACL policy deny
|
||
|
||
Management API not externally exposed except through frontend/reverse proxy
|
||
|
||
Database not host exposed
|
||
|
||
Dynamic Security administration listener internal only
|
||
|
||
No Docker socket exposure
|
||
```
|
||
|
||
Dynamic Security supports deny-by-default ACL behaviour and runtime modification of clients, groups and roles.
|
||
|
||
---
|
||
|
||
# 59. Initial installation workflow
|
||
|
||
On first startup:
|
||
|
||
```text
|
||
PostgreSQL starts
|
||
↓
|
||
Backend migrations run
|
||
↓
|
||
Initial management admin created
|
||
↓
|
||
Dynamic Security initialized
|
||
↓
|
||
Mosquitto admin identity initialized
|
||
↓
|
||
Default broker config generated
|
||
↓
|
||
CA setup checked
|
||
↓
|
||
Mosquitto starts
|
||
↓
|
||
Backend verifies broker
|
||
↓
|
||
Frontend becomes ready
|
||
```
|
||
|
||
If no PKI exists, the administrator should see:
|
||
|
||
```text
|
||
MQTT TLS is not yet configured.
|
||
|
||
[Create internal CA]
|
||
[Import CA]
|
||
[Configure later]
|
||
```
|
||
|
||
---
|
||
|
||
# 60. Initial default broker configuration
|
||
|
||
A secure installation should initially expose only an internal administration connection until the administrator configures the production listener.
|
||
|
||
Typical production result:
|
||
|
||
```text
|
||
listener 8883
|
||
|
||
TLS enabled
|
||
server certificate configured
|
||
anonymous disabled
|
||
dynamic security enabled
|
||
persistence enabled
|
||
logging enabled
|
||
```
|
||
|
||
An optional mTLS profile would additionally enable:
|
||
|
||
```text
|
||
require_certificate true
|
||
```
|
||
|
||
---
|
||
|
||
# 61. Mosquitto configuration ownership
|
||
|
||
The frontend shall never be considered the actual configuration store.
|
||
|
||
The ownership hierarchy shall be:
|
||
|
||
```text
|
||
PostgreSQL configuration model
|
||
│
|
||
▼
|
||
Generated configuration revision
|
||
│
|
||
▼
|
||
mosquitto.conf
|
||
│
|
||
▼
|
||
Mosquitto
|
||
```
|
||
|
||
This allows validation, auditing, versioning and rollback.
|
||
|
||
---
|
||
|
||
# 62. Rollback
|
||
|
||
Each successfully deployed configuration shall be recoverable.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Revision 53
|
||
↓
|
||
configuration causes problem
|
||
↓
|
||
Select revision 52
|
||
↓
|
||
Validate
|
||
↓
|
||
Deploy
|
||
↓
|
||
Reload/restart
|
||
```
|
||
|
||
Rollback itself shall create a new revision rather than modifying history.
|
||
|
||
Example:
|
||
|
||
```text
|
||
52
|
||
53
|
||
54 = rollback to contents of 52
|
||
```
|
||
|
||
---
|
||
|
||
# 63. Database migrations
|
||
|
||
Database schema changes shall use Alembic migrations.
|
||
|
||
Backend startup shall either:
|
||
|
||
* automatically apply compatible migrations; or
|
||
* fail readiness and require an explicit migration command.
|
||
|
||
Production deployments should favour explicit migrations.
|
||
|
||
---
|
||
|
||
# 64. API tests
|
||
|
||
Automated tests shall cover at minimum:
|
||
|
||
```text
|
||
authentication
|
||
authorization
|
||
client creation
|
||
ACL creation
|
||
certificate issuance
|
||
certificate revocation
|
||
configuration generation
|
||
configuration validation
|
||
configuration rollback
|
||
audit creation
|
||
backup/restore
|
||
```
|
||
|
||
---
|
||
|
||
# 65. Integration tests
|
||
|
||
An automated test environment shall launch an actual Mosquitto container.
|
||
|
||
Tests shall verify:
|
||
|
||
```text
|
||
MQTT username/password authentication
|
||
mTLS authentication
|
||
certificate CN mapping
|
||
ACL allow
|
||
ACL deny
|
||
group ACL
|
||
role ACL
|
||
client disable
|
||
certificate revocation
|
||
configuration reload
|
||
broker restart
|
||
```
|
||
|
||
---
|
||
|
||
# 66. Security tests
|
||
|
||
Security testing shall include:
|
||
|
||
```text
|
||
authentication bypass attempts
|
||
horizontal privilege escalation
|
||
vertical privilege escalation
|
||
CSRF
|
||
XSS
|
||
SQL injection
|
||
path traversal
|
||
malicious certificate upload
|
||
malformed CSR
|
||
secret exposure
|
||
Docker breakout exposure
|
||
API rate abuse
|
||
```
|
||
|
||
---
|
||
|
||
# 67. Recommended repository structure
|
||
|
||
```text
|
||
mqtt-platform/
|
||
│
|
||
├── compose.yaml
|
||
├── .env.example
|
||
├── README.md
|
||
│
|
||
├── frontend/
|
||
│ ├── Dockerfile
|
||
│ ├── package.json
|
||
│ └── src/
|
||
│
|
||
├── backend/
|
||
│ ├── Dockerfile
|
||
│ ├── pyproject.toml
|
||
│ ├── migrations/
|
||
│ └── app/
|
||
│
|
||
├── broker-control/
|
||
│ ├── Dockerfile
|
||
│ └── app/
|
||
│
|
||
├── mosquitto/
|
||
│ ├── templates/
|
||
│ └── bootstrap/
|
||
│
|
||
├── scripts/
|
||
│
|
||
└── tests/
|
||
├── unit/
|
||
├── integration/
|
||
└── e2e/
|
||
```
|
||
|
||
Generated configuration and secrets shall not be stored in Git.
|
||
|
||
---
|
||
|
||
# 68. MVP scope and release plan
|
||
|
||
The original single "first release" list contained roughly 25 sub-systems and is not achievable as one release. The MVP is therefore split into three releases. Each release is independently deployable and useful, and each builds on the previous one.
|
||
|
||
## 68.1 Release 1 — Core broker administration
|
||
|
||
Goal: deliver the original core requirement — a web-managed Mosquitto broker with client authentication and authorization, including ACLs, without touching files on the host.
|
||
|
||
```text
|
||
Docker Compose stack
|
||
|
||
Mosquitto 2.1.x (pinned)
|
||
|
||
PostgreSQL
|
||
|
||
FastAPI backend
|
||
|
||
React frontend
|
||
|
||
Management authentication (sessions, Argon2id, ADMIN_INITIAL_* bootstrap)
|
||
|
||
Management RBAC (core roles)
|
||
|
||
Dynamic Security integration (backend as MQTT admin client)
|
||
|
||
MQTT clients (create/disable/enable/delete, password reset, random passwords)
|
||
|
||
Groups
|
||
|
||
Roles
|
||
|
||
ACL editor (all six ACL types, %u/%c patterns, priorities)
|
||
|
||
Broker configuration editor (basic + advanced mode)
|
||
|
||
Listener configuration
|
||
|
||
Configuration validation (--test-config)
|
||
|
||
Configuration generation from the PostgreSQL model
|
||
```
|
||
|
||
Release 1 delivers a secure default broker configuration and removes the need to edit
|
||
`mosquitto.conf`, the Dynamic Security JSON, or password files manually.
|
||
|
||
## 68.2 Release 2 — PKI, versioning, and controlled change
|
||
|
||
Goal: make TLS/mTLS and broker configuration changes safe and auditable.
|
||
|
||
```text
|
||
CA creation (internal CA, import CA)
|
||
|
||
Server certificate generation (CN, SANs, key algorithm/length)
|
||
|
||
Client certificates (managed-key mode, one-time download)
|
||
|
||
CSR signing
|
||
|
||
Certificate revocation and CRL generation/publishing
|
||
|
||
mTLS listeners (require_certificate, use_identity_as_username)
|
||
|
||
Configuration revisions (history, diff)
|
||
|
||
Configuration deployment with health check
|
||
|
||
Broker reload (mosquitto_signal / SIGHUP), reload-vs-restart classification
|
||
|
||
Configuration rollback (rollback creates a new revision)
|
||
|
||
mosquitto-control service (validate, activate, signal, health check)
|
||
```
|
||
|
||
## 68.3 Release 3 — Operations, safety, and visibility
|
||
|
||
Goal: make the platform usable for daily operation and secure change management.
|
||
|
||
```text
|
||
ACL simulator (with parity tests against real broker decisions)
|
||
|
||
Dashboard ($SYS monitoring, broker status)
|
||
|
||
Certificate expiry monitoring and dashboard warnings
|
||
|
||
Audit logging (all privileged actions)
|
||
|
||
Backup and restore (logical backup, encrypted)
|
||
|
||
Configuration drift detection
|
||
|
||
Client metadata/tags (owner, purpose, last known connection)
|
||
|
||
Connected-client view (where available)
|
||
```
|
||
|
||
## 68.4 Post-MVP
|
||
|
||
Topic explorer, MQTT test client, connection tester, client provisioning wizard,
|
||
bridge configuration, retained-message administration, Prometheus metrics, external
|
||
notifications, and the approval workflow remain post-MVP features as previously
|
||
planned (see sections 69 and 70).
|
||
|
||
---
|
||
|
||
# 69. Post-MVP: Phase 2
|
||
|
||
After the three MVP releases (section 68) are complete, the next phase should add:
|
||
|
||
```text
|
||
Topic explorer
|
||
MQTT test client
|
||
Connection tester
|
||
Client provisioning wizard
|
||
Bridge configuration
|
||
Certificate expiry alerts
|
||
Config drift detection
|
||
Retained message administration
|
||
Client metadata/tags
|
||
Configuration approval workflow
|
||
Prometheus metrics
|
||
External notification mechanisms
|
||
```
|
||
|
||
---
|
||
|
||
# 70. Post-MVP: Phase 3
|
||
|
||
Potential advanced functionality:
|
||
|
||
```text
|
||
MQTT topic namespace registry
|
||
JSON Schema registry
|
||
payload validation
|
||
device inventory integration
|
||
automatic certificate renewal
|
||
ACME/SCEP/EST integration
|
||
LDAP/Active Directory/OIDC login
|
||
external PKI integration
|
||
multiple Mosquitto brokers
|
||
broker federation
|
||
HA deployment
|
||
configuration-as-code export
|
||
Git integration
|
||
API-driven provisioning
|
||
```
|
||
|
||
---
|
||
|
||
# 71. Particularly recommended additional frontend functionality
|
||
|
||
Beyond the original requirements, the features with the highest operational value are:
|
||
|
||
**Configuration versioning and rollback**
|
||
Mosquitto configuration should be treated like controlled configuration rather than an editable text file.
|
||
|
||
**ACL simulator**
|
||
Makes complex authorization understandable before deployment.
|
||
|
||
**Client provisioning wizard**
|
||
Makes creation of credentials, certificates and ACL assignments consistent.
|
||
|
||
**Certificate lifecycle dashboard**
|
||
Expiration, revocation and ownership become difficult to manage manually as the number of clients increases.
|
||
|
||
**Topic explorer and MQTT test client**
|
||
Extremely useful when commissioning devices and troubleshooting.
|
||
|
||
**Configuration drift detection**
|
||
Detects manual changes outside the platform.
|
||
|
||
**Audit logging**
|
||
Provides traceability for security and configuration changes.
|
||
|
||
**Broker diagnostics and `$SYS` monitoring**
|
||
Makes the platform useful for daily operation rather than only configuration.
|
||
|
||
**Bridge management**
|
||
Particularly valuable for distributed broker architectures.
|
||
|
||
**Topic namespace registry**
|
||
Turns the system from merely a broker manager into a controlled MQTT information-management platform.
|
||
|
||
---
|
||
|
||
# 72. Architectural target
|
||
|
||
The intended platform can ultimately be viewed as four layers:
|
||
|
||
```text
|
||
┌─────────────────────────────────────────────┐
|
||
│ MQTT Management UI │
|
||
│ │
|
||
│ Broker | Clients | ACL | PKI | Monitoring │
|
||
└──────────────────────┬──────────────────────┘
|
||
│
|
||
┌──────────────────────▼──────────────────────┐
|
||
│ Management API │
|
||
│ │
|
||
│ Auth | RBAC | PKI | Config | Audit | MQTT │
|
||
└────────────┬───────────────────┬────────────┘
|
||
│ │
|
||
┌────────────▼─────────┐ ┌───────▼────────────┐
|
||
│ PostgreSQL │ │ Broker management │
|
||
│ │ │ / Dynamic Security │
|
||
└─────────────────────┘ └───────┬────────────┘
|
||
│
|
||
┌────────▼─────────┐
|
||
│ Mosquitto │
|
||
│ │
|
||
│ MQTT / TLS/mTLS │
|
||
└──────────────────┘
|
||
```
|
||
|
||
The result should behave as a self-contained **MQTT broker management platform**, rather than simply a graphical editor for `mosquitto.conf`.
|