[rabbitmq-discuss] RPC authenticity relies on routing key?
matthew at lshift.net
Fri Mar 12 12:10:36 GMT 2010
On Thu, Mar 11, 2010 at 02:03:20PM -0700, Nathaniel Haggard wrote:
> Machine D sends a message to exchange E1 with routing key send_to_A to
> execute a remote procedure call on A. A replies back using another
> exchange E2 with routing key results_of_A, but A could easily use the
> key results_of_B. Does rabbitmq have a way of making A only use the
> key results_of_A?
No. Rabbit is just a router, and there are several issues with trying to
do RPC. You really have to come up with your own conventions here, and
Rabbit (nor any other AMQP broker) will force your hand.
One of the issues is that in AMQP world, you have no idea how many
people have received your messages - several queues could exist bound to
E1 with the binding key send_to_A and thus they'll all receive the rpc.
Thus you're inventing convention even at that point if you stipulate
that only one queue can have the binding key send_to_A.
> Only D can write to E1. A, B, C can write to E2. I suppose A, B, C
> are all different users in the system although that seems overkill.
There's nothing wrong with A, B and C all being different users, but
then again, they could all be the same user. Depends on other
requirements really. If one of A, B and C goes nuts, you could just
individually revoke permissions for them to stop them publishing.
> Is there a better way to make sure the results from an RPC to A are
> really from A and not from B?
Yes. For each of A, B and C, D creates a private queue which it is the
exclusive consumer on. These queues are automatically bound to the
default direct exchange. Then include the queue name in the reply_to
field in the publish class properties. When A, B or C receives the
message, they route their reply to the default exchange, using the value
in the reply_to field as the routing key. As the queue names are guids
and (as good as) unforgeable, you can be sure that they can't invent the
other queue names.
> I think it would not scale well (in the thousands) if A, B, C each had
> permissions to write to one queue exchanges E2, E3, and E4, but maybe
> that's wrong too.
I think in this case you're better off relying on unforgeability of
anonymous queue names, rather than the slightly restrictive permissions
The other solution would be to implement a custom exchange, which you
can now do very easily with Rabbit's pluggable exchange types. In there
you could do many additional checks and implement whatever permission
model you'd like.
More information about the rabbitmq-discuss