DEV Community

Kohei Kawata
Kohei Kawata

Posted on

Deployment pipeline of Azure Service Bus with Managed Identity authentication

Summary

Azure Managed Identity works for Azure resource authentication without secret keys. Among some authentication method options, this is the best way to secure the system as secret key management costs you a lot, for example, key storage, rotation, leakage management etc. However, managed identity authentication requires a bit more work to build infrastructure of the system because it needs high privileged permissions of Azure AD (Active Directory) and Azure Subscription, which makes it difficult to build automated deployment pipelines.

Related sample codes

TOC

Context

Service Bus authentication options

Azure Service Bus has three options for its authentication method.

  • Shared Access Signature

    • Set up a policy for each queue and topic such as Listen, Send, Manage and issue a shared access signature (similar to connection string). This allows you to grant least privileged permissions to different topics and queues. The problem of this method is it requires secret key management.
  • Azure AD Service Principal

    • You register apps in Azure AD and generate a secret key. A client app can receive a token by submitting the registered app's client ID and secret key. This also requires secret key management.
  • Azure AD Managed Identity

    • You issue a managed identity (System-assinged or User-assigned) in a client app resource, for example, Azure Virtual Machine, Azure Web App, Azure Functions, etc. Then you grant Service Bus permissions to the managed identity (Azure AD Object ID) so the client app can access Service Bus. The client app runs a code like .NET application with Azure.Identity package.

Problems of Managed Identity authentication

This method does not require secret key management, which is very secure, but requires Azure Subscription Owner role. This has to be a problem for an automated deployment pipeline because you do not want to grant Subscription owner role to Azure DevOps pipeline service principal. The Azure DevOps service principal has rights to deploy Azure resources through the Infrastructure as Code pipeline, but does not have a right to set up managed identity access for Service Bus. Then you need to have at least one manual step in the pipeline.

Image description

Azure role and Azure AD role

In the beginning, I was confused of differnce between Azure role and Azure AD role. For Service Bus authenticaiton, you are required to have Subscription Owner role, which is Azure role, not Azure AD role. Below shows difference between Azure role and Azure AD role.

Azure role (RBAC)

  • Target
    • Azure subscription
    • Azure resource access
  • Built-in role examples
    • Owner
    • Contributor
    • Reader
    • Azure Service Bus Data Receiver
    • Azure Service Bus Data Sender
  • Required for assignment
    • Owner
    • User Access Administrator
    • Microsoft.Authorization/roleAssignments/write
  • Assignment tool
    • Azure Portal (IAM)
    • Powershell
    • Azure CLI
    • REST API

Azure AD role

  • Target
    • Azure tenant
    • User, Group, Service Principal, Graph API
  • Built-in role examples
    • Global Administrator
    • Application Developer
    • User Administrator
    • Billing Administrator
  • Required for assignment
    • Global Administrator
    • Privileged Role Administrator
    • microsoft.directory/roleAssignments/allProperties/allTasks
  • Assignment tool
    • Azure Portal
    • Powershell
    • Microsoft Graph API

Deployment pipeline

Assign Azure roles of Service Bus

After a IaC pipeline deployes Azure App Service and Azure Service Bus, you need to assign the necessary Azure roles to the managed identity of App Service. If the app reads and writes messages to Service Bus, both Azure Service Bus Data Receiver and Azure Service Bus Data Sender roles have to be assigned. (Contributor role is not enough)

With Subscription Owner or User Access Administrator role, you run the powershell command below on Azure.

$RoleReceiver = "Azure Service Bus Data Receiver"
$RoleSender = "Azure Service Bus Data Sender"
$AppServiceObjectId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
$SubscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
$ResourceGroup = "rg-sample-dev"
$ServiceBusNamespace = "sb-sample-dev"

az role assignment create `
--role $RoleReceiver `
--assignee $AppServiceObjectId `
--scope /subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.ServiceBus/namespaces/$ServiceBusNamespace

az role assignment create `
--role $RoleSender `
--assignee $AppServiceObjectId `
--scope /subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.ServiceBus/namespaces/$ServiceBusNamespace
Enter fullscreen mode Exit fullscreen mode

Reference

Oldest comments (0)