RabbitMQ - defining user permissions to resources?

3,365 views
Skip to first unread message

Mobile Mouse

unread,
Dec 28, 2014, 11:29:39 PM12/28/14
to rabbitm...@googlegroups.com
Following Michael’s request, starting a new/separate discussion for this access control question. 

On Dec 26, 2014, at 17:07 , Jean-Sébastien Pédron <jean-se...@rabbitmq.com> wrote:
On 26.12.2014 18:51, Mobile Mouse wrote:
Say, I have two users “Pete” and “Joe”. I have one virtual host “test”.

It has two exchanges: “colors” and “shapes”. Exchange “colors” has three
queues: “red”, “blue”, and “green”.

I want to authorize Joe to be able to read from “red” and to read/write
to “blue”. No other access.

I want to authorize “Pete” to read and write to “green”, and to have
complete access to exchange “shapes”. No other access.

A message is published to an exchange, not a queue. You can control
publish (write) access to a particular exchange ("colors" in your case),
but not a particular queue ("blue" here).

I see. 

So the ability to write to one queue on a given exchange implies the ability to write (publish) to any queue on this exchange. But to bind a queue he needs a write access to that queue, and to read from it he needs read access for this queue. Correct?

However, you can control consumers access to given queues by tuning the
read permission. Thus, you can restrict read access to "red" and “blue.

Here I think my understanding is still lacking.

In order to read from a queue, consumer needs to queue.bind that queue first - correct? Thus in order to read from a queue the user needs to have (a) “write” permission for the queue and “read” for the exchange that hosts this queue to bind the queue, and (b) “read” permission for the queue itself to actually consume messages from it?


Does a queue name include the name of the exchange it in on, or is in any way bound to it? Is there any way to specify that the permission/access rule is meant for a queue on a specific/given exchange? 

For example, there is a queue named “red” on two exchanges (e.g. exchange “bright_colors” and exchange “subdued_colors”). Is it possible to somehow specify that a user is allowed to read from “red” on “bright_colors”, but not from the one on the other exchange? Especially if I want this user to read from other queues on the other exchange (but not from the “red” queue)?


Here's an example for Joe:

rabbitmqctl set_permissions \
   Joe \
   '^(colors|blue|red)$' \
   '^(colors|blue|red)$' \
   '^(colors|blue|red)$'

Now, Joe is allowed to declare the "colors" exchange and the "blue" and
"red" queues, and bind them together.

Does it mean that if there’s an exchange also named “blue”, then Joe would have complete access to that exchange as well, not only to the queue “blue”? 

If I want to avoid this kind of thing/confusion/overlap - the only way to do that is to make sure there is no name collision between entity classes? Maybe by prefixing exchange names with “e-“, and queue names with “q-“ or such?

Thanks!!

Jean-Sébastien Pédron

unread,
Dec 29, 2014, 5:15:36 AM12/29/14
to rabbitm...@googlegroups.com
On 29.12.2014 05:29, Mobile Mouse wrote:
> So the ability to write to one queue on a given exchange implies the
> ability to write (publish) to any queue on this exchange. But to bind a
> queue he needs a write access to that queue, and to read from it he
> needs read access for this queue. Correct?

Yes

>> However, you can control consumers access to given queues by tuning the
>> read permission. Thus, you can restrict read access to "red" and “blue.
>
> Here I think my understanding is still lacking.
>
> In order to read from a queue, consumer needs to /queue.bind/ that
> queue first - correct?

Any client can bind the queue. A consumer is just a client who gets
messages from queues. It could produce messages too.

> Thus in order to read from a queue the user needs to have (a) “write”
> permission for the queue and “read” for the exchange that hosts this
> queue to bind the queue, and (b) “read” permission for the queue
> itself to actually consume messages from it?

Yes, though the declaration of the exchange/queue/binding could be done
by another client if you want.

Except if you have a bootstrap process for your RabbitMQ node/cluster,
it's often safer if all your clients declare the resources they will
use. By doing that, clients will be able to work, no matter which one
connects first.

It's better explained in the "Receiving" paragraph of tutorial #1:
http://www.rabbitmq.com/tutorials/tutorial-one-python.html

> Does a queue name include the name of the exchange it in on, or is
> in any way bound to it? Is there any way to specify that the
> permission/access rule is meant for a queue on a specific/given
> exchange?

No, because the consumer does only know the queue it is reading from,
not where the message comes from.

>> rabbitmqctl set_permissions \
>> Joe \
>> '^(colors|blue|red)$' \
>> '^(colors|blue|red)$' \
>> '^(colors|blue|red)$'
>
> Does it mean that if there’s an exchange also named “blue”, then Joe
> would have complete access to that exchange as well, not only to the
> queue “blue”?

Yes.

> If I want to avoid this kind of thing/confusion/overlap - the only way
> to do that is to make sure there is no name collision between entity
> classes? Maybe by prefixing exchange names with “e-“, and queue names
> with “q-“ or such?

Exact.

--
Jean-Sébastien Pédron
Pivotal / RabbitMQ

Amrita Dhawan

unread,
Feb 4, 2026, 9:04:04 AM (8 days ago) Feb 4
to rabbitmq-users

Hi RabbitMQ team,

Implementing secure synchronous RPC with Qpid JMS over RabbitMQ AMQP 1.0. Core issue: responders require amq.default write permissions despite using dedicated exchanges, defeating per-queue security.

Current Flow (Fails)
text
Requester → /exchanges/app1/queueA (works ✓) replyTo: /queues/queueA.reply (works ✓) Responder → read /queues/queueA (works ✓) → reply /exchanges/app1/queueA.reply (FAILS ✗)

Why it fails:

  1. Qpid treats /queues/queueA.reply replyTo as queue-direct (default exchange internally)

  2. Responder reply publish requires amq.default write → can publish to any queue

  3. /exchanges/app1/queueA.reply address rejected by Qpid client (address homogeneity?)

Desired Flow
text
Requester → /exchanges/app1/queueA replyTo: /queues/user1-reply-Q (fixed durable) Responder → read /queues/queueA → reply /exchanges/app1/user1-reply-Q

With user perms only on app1 exchange (no amq.default access).

Questions
  1. Recommended pattern for AMQP 1.0 RPC avoiding default exchange permissions entirely?

  2. Any RabbitMQ AMQP 1.0 addressing quirks or required bindings I'm missing?

Setup: RabbitMQ 4.1.0 + AMQP 1.0 plugin, Qpid JMS client, durable reply queues pre-bound to app1.

Thanks for guidance on secure RPC patterns!

Reply all
Reply to author
Forward
0 new messages