Securing Azure Messaging Service Bus accessSolution ·
I am currently working on a very exciting project involving systems integration across the Azure Messaging Service Bus. I thought I would share some of the painfully acquired knowledge nuggets with you.
About %90 of examples you'll find on Internet uses Azure Bus SDK with 'owner'. That is basically 'admin' privilege because owner has read/write AND manage on an entire Service Bus namespace.
Although that is ok nice to get use to the SDK, but isn't a very secure setting for a production environment. Indeed, if the owner credentials get compromise, it would compromise the entire namespace. To top it, Microsoft recommends not to change the password & symmetric key of the owner account!
So what is it we can do?
I'll give you a few guidelines here but you can read in length on this excellent blog post or watch Clemens Vasters's video.
Entities in Service Bus (i.e. Queues, Topics & Subscriptions) are modelled as relying parties in a special Azure Access Control Service (ACS): the Service Bus trust that its buddy-ACS, i.e. the one having the same name with a -sb happened to it, as a token Issuer. So access control is going to happened in that ACS.
You do not have access to that ACS directly, you must pass by the Service Bus page:
Once on that ACS, you can find the Service Identities tab:
And there, you'll find our friend the owner:
So owner is actually a Service Identity in the buddy-ACS of the Service Bus.
Now, let's look at the relying parties:
As I said, Relying parties represents Service Bus' entities. Basically, any topic is the realm:
while any subscription is
http://<namespace>.servicebus.windows/net/<topic name>/Subscriptions/<subscription name>
But there is a twist: if you do not define a relying party corresponding exactly to you entity, ACS will look at the other relying parties, basically chopping off the right hand side of the realm until it finds a matching realm. In this case here, since I haven't define anything, the root of my namespace is the fallback realm.
If we click on Service Bus, we see the configuration of the Service Identity and at the end:
The permissions are encoded in the rules. A rule is basically an if-then statement: if that user authenticates against this relying party, emit that claim. For Service Bus, the only interesting claim type is net.windows.servicebus.action:
So here you have it. Service bus performs access control with the following steps:
- Check ACS for a relying party corresponding to the entity it's looking at
- If that relying party can't be found, strip url parts until finding one
- ACS runs the rules of the relying party with the Service Identity of the consumer
- ACS returns a SWT token with claims in it
- Service Bus looks for the claim corresponding to the action it requires to do: Listen (receiving messages), Send & Manage.
So… if you want to give access by a specific agent (e.g. web role) to send messages on a topic, you create a Service Identity for the agent and create a relying party corresponding to the topic. You then enter a rule that emits a Send action and you should be all set.
This requires you to store secrets about to (Service) entity in the agents.
Hope this very quick overview gives you some ideas. As mentioned at the beginning, I recommend you read this excellent blog post or watch Clemens Vasters's video.