RabbitMQ permissions are set per user and per virtual host as three regular expressions: configure, write and read. A user may act on a queue or exchange only when its name matches the right expression. Give each application its own vhost permissions, and keep the patterns as narrow as the names allow.
The three permissions
The RabbitMQ access control documentation defines them this way. Configure covers creating or deleting a resource and changing its behaviour. Write covers publishing messages into a resource. Read covers retrieving messages from a resource.
Each is a regular expression matched against the resource name. The documentation notes that .* matches everything, while an empty string or ^$ matches nothing, which effectively blocks that permission.
Patterns for common roles
These are starting points, not copy and paste answers. Adjust the names to your own convention.
- A producer that publishes to one exchange: configure empty, write set to the exchange name, read empty.
- A consumer of one queue: configure empty, write empty, read set to the queue name.
- A service that declares its own queues: configure limited to a prefix such as the service name, so it cannot touch other teams' queues.
Anchor your patterns. Without anchors, a pattern for orders can also match names that merely contain it. The docs example for server generated names uses an anchored form for exactly this reason.
Operations need combinations
A single action can need more than one permission. The documentation gives the example that binding a queue needs write on the queue and read on the exchange. If a consumer fails right after you tighten rights, check which combination the failing call needs before you widen anything.
Vhosts as a boundary
Exchanges and queues live inside a vhost, so the same name in two vhosts refers to two different resources. A connection targets one vhost, and if the user has no permissions there, the connection is refused. The production checklist suggests separate vhosts per tenant and per environment in multi-tenant setups. That gives a clean blast radius: a leaked credential for one vhost does not open the others.
One caution from the docs: rabbitmq.conf can pre-grant a user permissions on new vhosts matching a pattern, and that should be used only for service accounts.
Topic permissions are opt in
For topic exchanges, there is a further check on the routing key. The documentation states that topic checks are opt in: if no topic permissions are defined, publishing and consuming are allowed. If you rely on routing keys to separate tenants, define the topic permissions explicitly. The default backend can use the connected username in the pattern.
Test the change
Permission checks may be cached per connection or channel, so changes may not apply until the client reconnects. Test with a throwaway client under the new user, try an action it should not be able to do, and confirm the refusal.
Safeguard can help here in a small way. Its SBOM and dependency scanning covers the broker client libraries and service frameworks your code pulls in, and reachability analysis shows which advisories your services actually call. You can try a free scan at gold.safeguard.sh/scan.
Quick check
What does a permission of empty string mean?
It matches nothing, so the user cannot perform that kind of operation on any resource in the vhost.
Do I need topic permissions?
Only if you want routing key level control. Without them, topic checks do not restrict anything.
Sources
Last reviewed: 19 October 2026.