This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Authentication and Access Control
Loading…
Authentication and Access Control
Relevant source files
This document explains the authentication and access control mechanisms available for the Mosquitto MQTT broker. The current configuration uses anonymous access, allowing any client that can reach the broker to connect without credentials. This page covers the implementation details, security implications, and alternative authentication strategies.
The Mosquitto broker supports multiple authentication methods:
- Anonymous Access : No credentials required (current configuration)
- Username/Password Authentication : Credential-based access control with password files
- Access Control Lists (ACLs) : Topic-level permissions based on usernames
- Plugin-Based Authentication : Custom authentication mechanisms via plugins
For the complete system security architecture, see Security Model. For advanced authentication configurations, see Protected Branch Features.
Current Configuration: Anonymous Access
The Mosquitto broker in this repository is configured for anonymous access, meaning no authentication is required for client connections. This is controlled by a single directive in the configuration file.
Configuration Location
The anonymous access setting is defined in mosquitto.conf2:
allow_anonymous true
This directive applies globally to all listeners defined in the configuration file. In this system, anonymous access affects both the standard MQTT listener on port 1883 and the WebSocket listener on port 9001 (see MQTT Protocol Listeners for details on these listeners).
Whatallow_anonymous true Means
| Configuration | Behavior |
|---|---|
allow_anonymous true | Clients can connect without username/password |
allow_anonymous false | Clients must provide valid credentials |
| (directive omitted) | Defaults to false in Mosquitto 2.0+ |
Sources: mosquitto.conf
Anonymous Access Connection Flow
Connection Flow Diagram
When allow_anonymous true is set in mosquitto.conf2 the Mosquitto broker accepts MQTT CONNECT packets regardless of whether they contain username/password credentials. The broker does not perform any authentication checks and immediately grants access to all MQTT operations.
Authentication Decision Logic
| MQTT CONNECT Contains | Credentials Checked? | Connection Result |
|---|---|---|
| Username + Password | No | Accepted |
| Username only | No | Accepted |
| No credentials | No | Accepted |
Sources: mosquitto.conf, README.md
Access Permissions with Anonymous Access
Unrestricted Topic Access
With allow_anonymous true and no ACL file configured in mosquitto.conf clients have unrestricted access:
| Permission Type | Anonymous Client Capabilities |
|---|---|
| SUBSCRIBE | Can subscribe to any topic, including wildcards (#, +) |
| PUBLISH | Can publish to any topic |
| RETAIN | Can set retained messages on any topic |
| QoS Levels | Full access to QoS 0, 1, and 2 |
| Topic Restrictions | None - all topics accessible |
| Will Messages | Can set last-will-and-testament messages |
Authentication Check Flow
Sources: mosquitto.conf
Security Implications
Trust Boundary Analysis
The security model for this configuration relies entirely on network-level access control rather than application-level authentication:
| Security Layer | Protection Provided | Configuration |
|---|---|---|
| Cloudflare Edge | DDoS protection, traffic filtering | Cloudflare Dashboard |
| Cloudflare Tunnel | Encrypted transport, no inbound ports | CLOUDFLARE_TUNNEL_TOKEN |
| Docker Network | Internal isolation between containers | docker-compose.yml |
| Mosquitto Authentication | None - anonymous access enabled | allow_anonymous: true |
Sources: mosquitto.conf, README.md
Threat Model Considerations
What Anonymous Access Protects Against:
- Direct internet exposure (mitigated by Cloudflare Tunnel)
- Port scanning and direct connection attempts (no inbound firewall rules required)
- DDoS attacks at the network level (handled by Cloudflare Edge)
What Anonymous Access Does NOT Protect Against:
- Unauthorized message publication by any client that reaches the broker
- Eavesdropping on topics by any connected client
- Malicious clients subscribing to all topics using
#wildcard - Topic flooding or message spam from authenticated clients
- Multi-tenant isolation (all clients can access all topics)
Sources: README.md
Appropriate Use Cases
When Anonymous Access Is Suitable
Anonymous access is appropriate in the following scenarios:
| Scenario | Rationale |
|---|---|
| Single-User Systems | One person controls all MQTT clients and traffic |
| Private/Home Networks | Network-level security already restricts access |
| Trusted Development Environments | Quick setup for testing without credential management |
| Internal IoT Networks | All devices within a trusted network boundary |
| Proof-of-Concept Deployments | Rapid prototyping without authentication complexity |
When Authentication Is Required
Authentication should be implemented when:
- Multiple users need isolated topic spaces
- Different clients require different permission levels
- Production deployments with untrusted client access
- Compliance or audit requirements mandate access control
- Topic-level security policies need enforcement
- Multi-tenant systems require user isolation
For these scenarios, see the alternative implementation in the [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/protected-no-wildcard branch) which provides username/password authentication and ACL-based topic restrictions. Detailed documentation is available at Protected Branch Features.
Sources: README.md
Configuration File Structure
The complete Mosquitto configuration from mosquitto.conf:1-5:
listener 1883
allow_anonymous true
listener 9001
protocol websockets
Configuration Analysis
| Line | Directive | Effect | Scope |
|---|---|---|---|
| 1 | listener 1883 | Defines standard MQTT listener | Port 1883 |
| 2 | allow_anonymous true | Enables anonymous access | Global (all listeners) |
| 3 | (blank) | Line separator | - |
| 4 | listener 9001 | Defines WebSocket listener | Port 9001 |
| 5 | protocol websockets | Specifies WebSocket protocol | Port 9001 only |
Key Observations
- The
allow_anonymous truedirective applies globally to both listeners - No
password_filedirective is present - No
acl_filedirective is present - No
allow_anonymousoverride on individual listeners - This creates a uniform anonymous access policy across MQTT and WebSocket protocols
Sources: mosquitto.conf
graph TB
ComposeFile["docker-compose.yml"]
MosqConf["mosquitto.conf"]
MosqContainer["mosquitto Container\n(eclipse-mosquitto:latest)"]
subgraph "Configuration Flow"
ComposeFile -->|Defines service| MosqContainer
MosqConf -->|Volume mount ./mosquitto.conf:/mosquitto/config/mosquitto.conf| MosqContainer
end
subgraph "Anonymous Access Config"
Line2["Line 2: allow_anonymous true"]
NoACL["No aclfile directive"]
NoPwdFile["No password_file directive"]
end
MosqConf --> Line2
MosqConf --> NoACL
MosqConf --> NoPwdFile
subgraph "Runtime Behavior"
AllowAll["All connections accepted"]
NoCredCheck["No credential validation"]
FullTopicAccess["Full topic access for all clients"]
end
Line2 --> AllowAll
NoACL --> FullTopicAccess
NoPwdFile --> NoCredCheck
Relationship to System Components
Container Configuration
The mosquitto service in docker-compose.yml mounts the configuration file as a volume:
This volume mount makes the allow_anonymous true setting effective when the container starts. The Mosquitto process reads this configuration file on startup and applies the anonymous access policy to all listeners.
Sources: mosquitto.conf, docker-compose.yml (referenced in diagrams)
Alternative Authentication Configurations
Username/Password Authentication
To enable credential-based authentication, modify mosquitto.conf to include:
allow_anonymous false
password_file /mosquitto/config/passwordfile
Create the password file using the mosquitto_passwd utility:
Authentication Flow with Credentials
| Configuration | Client Connect Behavior | Result |
|---|---|---|
allow_anonymous false | ||
password_file set | CONNECT without credentials | Connection rejected (CONNACK with return code 5) |
allow_anonymous false | ||
password_file set | CONNECT with valid credentials | Connection accepted |
allow_anonymous false | ||
password_file set | CONNECT with invalid credentials | Connection rejected (CONNACK with return code 4) |
Access Control Lists (ACLs)
ACLs provide topic-level permission control based on usernames. Add to mosquitto.conf:
acl_file /mosquitto/config/aclfile
ACL File Example
# User 'alice' can read/write to alice/* topics
user alice
topic readwrite alice/#
# User 'bob' can only read bob/* topics
user bob
topic read bob/#
Protected Branch Example
The [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/protected-no-wildcard branch) demonstrates a complete authentication implementation:
| Feature | Main Branch | Protected Branch |
|---|---|---|
| Authentication | Anonymous | Username/password required |
| Topic Access | Unrestricted | ACL-based restrictions |
| Wildcard Subscriptions | Allowed | Restricted to user’s namespace |
| Configuration Files | mosquitto.conf only | mosquitto.conf + ACL file + password file |
| Retained Messages | Unencrypted | Encrypted with gocryptfs |
For implementation details, see Protected Branch Features.
Sources: README.md
Testing Anonymous Access
The CI/CD pipeline validates that the Mosquitto broker starts successfully with anonymous access enabled. The health check in .github/workflows/ci.yml verifies the container reaches a running state but does not test authentication behavior since none is required.
Testing Approach
To manually verify anonymous access behavior:
- Start the services:
docker compose up - Connect any MQTT client to the public hostname configured in Cloudflare
- Attempt to connect without providing credentials
- Verify successful connection and message publication
No username or password should be required for successful connection and full MQTT operation.
Sources: .github/workflows/ci.yml (referenced), README.md
Migration Path to Authentication
If anonymous access proves insufficient for security requirements, the system can be migrated to authenticated access by:
- Creating a password file with
mosquitto_passwdcommand - Adding
password_file /path/to/password_filedirective to mosquitto.conf - Removing or changing
allow_anonymous truetoallow_anonymous false - Optionally adding an ACL file for topic-level restrictions
- Updating client code to provide credentials in CONNECT packets
The [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/protected-no-wildcard branch) provides a complete reference implementation. View the [configuration differences](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/configuration differences) to understand required changes.
For production deployments requiring authentication, see Production Considerations and Topic Access Control (ACL).
Sources: README.md
Dismiss
Refresh this wiki
Enter email to refresh