I have read the Get Started guide provided by RabbitMQ and have even contributed the sixth example to stormed-amqp, so I have an inkling of knowledge about AMQP.
However
TLDR: The relevant information can be found here: https://www.rabbitmq.com/access-control.html. However, since the rabbitmq documentation is very verbose, below I will describe what seems like the only solution to locking down access to resources.
As Michael Dillon mentions, you should start by making everything happen inside vhosts
(virtual hosts) and block the generic vhost
entirely. The generic vhost is simply called /
and is by default the only vhost
when you start a rabbitmq server.
A given resource (i.e. queue or exchange) must live in one vhost
and one vhost
only. A rabbitmq connection must also specifically connect to a single vhost
(this can just be specified by appending the vhost
name to the rabbitmq URL e.g. amqp://username:password@myserver:5672/vhost
). Therefore a rabbitmq connection can only access queues and exchanges that live in the vhost
it has connected to.
Simply create as many vhosts
as there are logical groupings in your application. Remember that resources in one vhost
are not aware of and cannot communicate with resources in another vhost
. Create a vhost
by doing:
rabbitmqctl add_vhost vhost-name
The next step is to create users and remove the default guest
user. Each user should have their own username and password which should be used only by them. Needless to say, only the actual administrator should have administrator privileges. This allows them to manage other users, vhosts
and their permissions. Create a user by doing:
rabbitmqctl add_user "username"
Users can use their credentials to create a rabbitmq connection and thereby connect to a vhost
. However, the connection is only approved if this is a vhost
the user has access to. Only an adminstrator can grant and modify a user's access permissions to a vhost
. A user can be granted access to multiple vhosts
and use their credentials to connect to multiple vhosts
simultaneously (but not different vhosts
within the same connection).
However, a user's access to a vhost
is not simply binary.
RabbitMQ distinguishes between configure, write and read operations on a resource. The configure operations create or destroy resources, or alter their behaviour. The write operations inject messages into a resource. And the read operations retrieve messages from a resource.
There is a nice table in the linked section of the docs which denotes what command counts as what kind of operation e.g. queue.bind
is a write
operation whereas queue.get
is a read
operation. However the complexity doesn't end there, permissions are actually granted to each operation type based on a custom regular expression (regex) of the administrator's choosing.
For instance the regex '.*' '.*' '.*'
allows the user to configure, write and read respectively on any resource in that vhost
. This would be granted like so:
rabbitmqctl set_permissions -p "vhost-name" "username" ".*" ".*" ".*"
Whereas the regex '^$' '^(hello).*$' '^(hello|world).*$'
would not give the user any configuration permissions but would allow them to write to any resource whose name began with hello
and read from any resource whose name began with either hello
or world
.
Use vhosts
liberally to group resources together and set permissions on these resources as a whole.
Naming of resources is very important as this is the only way to configure access to that resource within a given vhost
.
In the case of the OP's question, each user should be permissioned to only read and write to their own queue based on the queue's unique name. This does not necessarily need to be across multiple vhosts
but can be if it makes sense for it to be.