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?
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.