RabbitMQ doesn’t actually enforce security settings unless you explicitly tell it to.

Let’s see what happens when we try to connect to a fresh RabbitMQ instance without any security configured.

# On a separate machine, try to connect to RabbitMQ's management UI
curl -I http://your_rabbitmq_host:15672

# Expected Output (will vary slightly):
# HTTP/1.1 401 Unauthorized
# Server: mochiweb/2.13.2
# Date: Tue, 15 Oct 2024 10:00:00 GMT
# Content-Type: text/plain; charset=utf-8
# Content-Length: 21
# WWW-Authenticate: Basic realm="RabbitMQ User 'guest' (source: http://your_rabbitmq_host:5672)"

See that 401 Unauthorized and WWW-Authenticate header? That’s RabbitMQ telling you, "Hey, I could ask for a username and password, but you haven’t set one up yet, so I’m just going to let you know I’m supposed to." The guest user is a default, and it’s only allowed to connect from localhost. If you try to connect from anywhere else, even if you did provide guest/guest, it would fail. This is a critical, often overlooked, security default.

To actually secure RabbitMQ, we need to define users, set passwords, and then assign permissions to those users on specific virtual hosts.

The Core Components of RabbitMQ Security:

  1. Users: These are the entities that will connect to RabbitMQ. Each user needs a username and a password.
  2. Virtual Hosts (vhosts): Think of these as isolated environments within a single RabbitMQ server. They allow you to partition your RabbitMQ instance for different applications or teams. Permissions are granted per vhost.
  3. Permissions: These define what actions a user can perform on a specific vhost. The key permissions are:
    • configure: Can declare, delete, and modify exchanges, queues, and bindings.
    • write: Can publish messages to exchanges.
    • read: Can consume messages from queues.

Setting Up Authentication and Permissions

Let’s walk through creating a user, a virtual host, and assigning permissions. We’ll use the RabbitMQ command-line tool, rabbitmqadmin, for this. Make sure rabbitmqadmin is in your PATH or specify its full path.

Step 1: Create a New User

First, let’s create a user named app_user with a strong password.

rabbitmqadmin declare user name=app_user password=SuperSecretPassword123

This command creates the user app_user in RabbitMQ’s internal authentication database.

Step 2: Create a Virtual Host

Now, let’s create a virtual host named my_app_vhost where our application will operate.

rabbitmqadmin declare vhost name=my_app_vhost

This creates a dedicated, isolated space for our application’s queues and exchanges.

Step 3: Grant Permissions to the User on the Virtual Host

Finally, we grant app_user full control (configure, write, read) over my_app_vhost.

rabbitmqadmin declare permission \
  --vhost=my_app_vhost \
  --user=app_user \
  --conf='.*' \
  --write='.*' \
  --read='.*'
  • --vhost=my_app_vhost: Specifies the virtual host to apply permissions to.
  • --user=app_user: Specifies the user receiving these permissions.
  • --conf='.*': Grants configure permissions for all resources (exchanges, queues, etc.) within the vhost. The .* is a regular expression.
  • --write='.*': Grants write permissions for all resources.
  • --read='.*': Grants read permissions for all resources.

Now, app_user can connect to RabbitMQ and interact with resources only within my_app_vhost. If app_user tries to access my_app_vhost with incorrect credentials, they’ll get a 401 Unauthorized. If they try to access a different vhost (like the default /), they’ll also get a 401 Unauthorized because they have no permissions there.

Connecting with the New User

When your application connects, it will use app_user and SuperSecretPassword123, targeting my_app_vhost.

# Example using curl to hit the management UI (replace with your actual credentials and host)
curl -I http://app_user:SuperSecretPassword123@your_rabbitmq_host:15672/vhosts/my_app_vhost

# Expected Output:
# HTTP/1.1 200 OK
# Server: mochiweb/2.13.2
# Date: Tue, 15 Oct 2024 10:05:00 GMT
# Content-Type: application/json
# Content-Length: 1234 # (Actual length will vary)

This 200 OK indicates successful authentication and authorization.

Beyond Basic Authentication: Resource-Specific Permissions

The .* wildcard is convenient, but for tighter security, you can specify more granular permissions. For instance, if you have a single exchange my_exchange and a single queue my_queue within my_app_vhost, and you want one user (publisher) to only publish and another (consumer) to only consume:

1. Create Users:

rabbitmqadmin declare user name=publisher password=PublisherPass123
rabbitmqadmin declare user name=consumer password=ConsumerPass456

2. Grant Permissions:

# Publisher can only write to 'my_exchange' (implicitly allows routing)
rabbitmqadmin declare permission \
  --vhost=my_app_vhost \
  --user=publisher \
  --conf='my_exchange' \
  --write='my_exchange' \
  --read='' # No read permission

# Consumer can only read from 'my_queue'
rabbitmqadmin declare permission \
  --vhost=my_app_vhost \
  --user=consumer \
  --conf='' \
  --write='' \
  --read='my_queue'

In this granular setup, the publisher user can declare and write to my_exchange but cannot read from any queues. The consumer user can read from my_queue but cannot publish or declare anything. If you need a user to both declare an exchange and publish to it, you’d need both --conf='my_exchange' and --write='my_exchange'.

The most surprising thing about RabbitMQ’s security model is how granular it is, allowing you to define permissions not just per virtual host, but per exchange, queue, and even routing key pattern. This means you can have a single user that is allowed to publish to one specific exchange but can only consume from a different specific queue, all within the same virtual host, without granting them broad .* privileges.

By default, RabbitMQ uses its internal database for user credentials. However, it can be configured to authenticate against external systems like LDAP or Active Directory using plugins. This is crucial for larger deployments where managing users directly within RabbitMQ becomes cumbersome.

The next step in securing your RabbitMQ deployment involves understanding TLS/SSL for encrypting traffic between clients and the broker.

Want structured learning?

Take the full Amqp course →