Files
mqtt-broker-stack/specification.md
T
2026-09-20 09:23:04 +02:00

2368 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`.