Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

Topic Access Control (ACL)

Relevant source files

Purpose and Scope

This document explains the Access Control List (ACL) functionality available in the protected-no-wildcard branch of this repository. The main branch deploys Mosquitto with anonymous access enabled and no topic restrictions. For production environments requiring user-based topic isolation and access control, the protected-no-wildcard branch provides ACL-based authorization.

For information about the anonymous access configuration in the main branch, see Anonymous Access. For encryption of retained messages, which is also available in the protected-no-wildcard branch, see Encrypted Retained Messages.

Sources : README.md:5-11

Overview

Mosquitto supports Access Control Lists (ACLs) that define which users can publish or subscribe to specific topics. The main branch of this repository uses allow_anonymous true in mosquitto.conf2 permitting unrestricted access to all MQTT topics. This configuration is suitable for trusted environments or development scenarios.

The protected-no-wildcard branch implements a user-based topic hierarchy where the first level of each topic path represents the username, enforced through an ACL file located at mosquitto/aclfile.

Sources : mosquitto.conf:1-6 README.md:5-11

Branch Comparison

Diagram: Configuration Differences Between Branches

FeatureMain BranchProtected-No-Wildcard Branch
Anonymous AccessEnabled (allow_anonymous true)Disabled
ACL FileNot presentmosquitto/aclfile
User AuthenticationNot requiredRequired
Topic RestrictionsNoneUsername-prefixed topics
Wildcard SearchesUnrestrictedRestricted to user's own topics

Sources : README.md:5-11 mosquitto.conf2

Accessing the Protected-No-Wildcard Branch

The protected-no-wildcard branch is available as a reference implementation for ACL-based access control. You can view the branch or compare it with the main branch:

  • Branch URL: https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/tree/protected-no-wildcard
  • Diff URL: https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/compare/main...protected-no-wildcard

To switch to this branch locally:

Sources : README.md11

ACL Pattern Architecture

The protected-no-wildcard branch implements a hierarchical topic namespace where each user operates within a topic prefix matching their username. This pattern prevents users from accessing topics belonging to other users while allowing full control within their own namespace.

Diagram: Topic Namespace Isolation

graph TB
    subgraph "Topic Hierarchy"
        root["MQTT Topic Root"]
user1_ns["alice/"]
user2_ns["bob/"]
user3_ns["charlie/"]
user1_devices["alice/devices/+"]
user1_sensors["alice/sensors/+"]
user1_commands["alice/commands/+"]
user2_devices["bob/devices/+"]
user2_sensors["bob/sensors/+"]
end
    
    subgraph "ACL Rules"
        acl_file["mosquitto/aclfile"]
rule_alice["user alice\ntopic alice/#"]
rule_bob["user bob\ntopic bob/#"]
rule_charlie["user charlie\ntopic charlie/#"]
end
    
 
   root --> user1_ns
 
   root --> user2_ns
 
   root --> user3_ns
    
 
   user1_ns --> user1_devices
 
   user1_ns --> user1_sensors
 
   user1_ns --> user1_commands
    
 
   user2_ns --> user2_devices
 
   user2_ns --> user2_sensors
    
 
   acl_file --> rule_alice
 
   acl_file --> rule_bob
 
   acl_file --> rule_charlie
    
 
   rule_alice -.->|Grants Access| user1_ns
 
   rule_bob -.->|Grants Access| user2_ns
 
   rule_charlie -.->|Grants Access| user3_ns

Sources : README.md7

ACL File Structure

The mosquitto/aclfile follows Mosquitto's ACL file format. Each entry defines permissions for a specific user, restricting their access to topics matching a pattern.

Basic ACL Syntax

user <username>
topic [read|write|readwrite] <topic-pattern>

Example ACL Configuration

# User alice can publish and subscribe to all topics under alice/
user alice
topic readwrite alice/#

# User bob can publish and subscribe to all topics under bob/
user bob
topic readwrite bob/#

# User charlie can only subscribe to charlie/sensors/# but publish to charlie/commands/#
user charlie
topic read charlie/sensors/#
topic write charlie/commands/#
ACL DirectiveDescription
user <username>Begins an ACL rule block for the specified username
topic read <pattern>Grants subscribe (read) permission for matching topics
topic write <pattern>Grants publish (write) permission for matching topics
topic readwrite <pattern>Grants both publish and subscribe permissions
# wildcardMatches all remaining topic levels
+ wildcardMatches a single topic level

Sources : README.md7

Access Control Flow

Diagram: ACL Authorization Flow

Sources : README.md7

Wildcard Search Restrictions

The protected-no-wildcard branch implements a "naive" restriction on wildcard searches. With the username-prefixed topic hierarchy, users are prevented from subscribing to wildcards that would cross user boundaries.

Allowed Wildcards

PatternDescriptionAllowed
alice/devices/+Single-level wildcard within user namespace✓ Yes
alice/sensors/#Multi-level wildcard within user namespace✓ Yes
alice/+/temperatureSingle-level wildcard in middle of path✓ Yes

Blocked Wildcards

PatternDescriptionBlocked Reason
#Root-level multi-level wildcardWould access all users' topics
+/sensors/#Wildcard at username levelWould access multiple users' topics
alice/../bob/sensors/#Topic traversal attemptNot valid MQTT topic

Sources : README.md7

Configuration Changes Required

When migrating from the main branch to the protected-no-wildcard branch, several configuration changes are necessary:

mosquitto.conf Changes

Required Additional Files

  1. mosquitto/aclfile : Create this file with appropriate user and topic rules
  2. Password file (if using password authentication): Use mosquitto_passwd utility to create

Docker Compose Volume Mount

The ACL file must be mounted into the mosquitto container:

Sources : README.md7 mosquitto.conf:1-6

Authentication Methods

With allow_anonymous false, Mosquitto requires authentication. The protected-no-wildcard branch supports several authentication mechanisms:

MethodConfigurationUse Case
Password Filepassword_file /mosquitto/config/passwordsSimple username/password authentication
Plugin Authauth_plugin /path/to/plugin.soDatabase-backed authentication
PSKpsk_file /mosquitto/config/psk_filePre-shared key authentication
Certificaterequire_certificate trueTLS client certificate authentication

The specific authentication method used in the protected-no-wildcard branch should be verified by examining the branch's mosquitto.conf.

Sources : mosquitto.conf2

Security Considerations

Diagram: Security Layer Defense in Depth

Benefits of ACL Implementation

  1. Topic Isolation : Users cannot access topics outside their namespace
  2. Wildcard Restriction : Prevents broad topic enumeration by unauthorized users
  3. Granular Control : Different read/write permissions per topic pattern
  4. Audit Trail : Clear definition of who can access what

Limitations

  1. Naive Implementation : The "naive" approach mentioned in the README indicates this is a basic pattern-matching implementation
  2. Topic Format Dependency : Security relies on clients following the username/ topic prefix convention
  3. No Dynamic ACL : Changes to the ACL file require container restart
  4. First-Level Only : Security boundary is only at the first topic level

Production Recommendations

For production deployments requiring robust access control:

  • Implement strict client validation to enforce topic naming conventions
  • Consider additional authentication layers (e.g., OAuth2, JWT)
  • Monitor for topic naming violations
  • Implement rate limiting per user
  • Use TLS client certificates for stronger authentication
  • Enable Mosquitto's logging for audit trails

Sources : README.md7

Migration Checklist

When migrating from the anonymous main branch to the ACL-protected branch:

  • Review the diff between branches: https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/compare/main...protected-no-wildcard
  • Create mosquitto/aclfile with user permissions
  • Update mosquitto.conf to disable anonymous access
  • Update mosquitto.conf to reference the ACL file
  • Create authentication mechanism (password file, plugin, etc.)
  • Update docker-compose.yml to mount ACL file
  • Update existing MQTT clients to use credentials
  • Update client topic subscriptions to use username prefix
  • Test access control with multiple users
  • Verify wildcard restrictions work as expected
  • Update monitoring/alerting for authentication failures

Sources : README.md:5-11

The protected-no-wildcard branch includes additional features beyond ACL:

  • Encrypted Retained Messages : Uses gocryptfs to encrypt retained messages at rest (see Encrypted Retained Messages)
  • Auto-save Retained Messages : Automatically persists retained messages after every message

These features complement the ACL implementation to provide a more secure MQTT broker deployment.

Sources : README.md:8-9