Give teams access to specific APIs in Azure API Management with custom roles

Give teams access to specific APIs in Azure API Management with custom roles

Whenever multiple teams contribute to the same central instance of Azure API Management, you need to think about a governance concept around that instance. In case teams should be able to control their own but only view other APIs, you will need to create a custom Azure API Management role.

Create a custom role

For Role Based Access Control (RBAC), Azure Api Management offer a few built-in roles. These roles are all tied to the whole API Management instance. For roles that only allow access to specific APIs, we need to create our own custom roles in PowerShell.

To create a role, that only allows to modify one existing API in Azure API Management, you can run the following script.

$apiId='/subscriptions/<SUBSCRIPION_ID>/resourceGroups/<RESOURE_GROUP>/providers/Microsoft.ApiManagement/service/<API_MANAGEMENT_NAME>/apis/<API_NAME>'
$objectId='<USER_OR_GROUP_WHO_SHOULD_GET_AUTHORIZED>'

# Inherit from an existing role
$role = Get-AzRoleDefinition "API Management Service Reader Role"
$role.Id = $null
$role.Name = 'RBAC Test API Contributor'
$role.Description = 'Has read access to the RBAC TEST API.'

# Add write permissions for APIs to the new role
$role.Actions.Add('Microsoft.ApiManagement/service/apis/write')
$role.Actions.Add('Microsoft.ApiManagement/service/apis/*/write')

# Scope write permissions only to a specific API
$role.AssignableScopes.Clear()
$role.AssignableScopes.Add($apiId)

# Create the new role
New-AzRoleDefinition -Role $role

# Assign to role to a user or group
New-AzRoleAssignment -ObjectId $objectId -RoleDefinitionName "$role.Name" -Scope $apiId

Modify the API with Terraform

Once the write permission on a specific API has been given, the user with the new access rights over a specifc API can use Terraform for example to modify this API. Below, you can find an example script, which creates a new API operation for the rbac-test-api API.

terraform {
  required_version = ">= 0.13"
  backend "local" {}

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 2.50.0"
    }
  }
}

provider "azurerm" {
  features {}
  subscription_id            = "<SUBSCRIPTION_ID>"
  tenant_id                  = "<TENANT_ID>"
  skip_provider_registration = "true"
}

resource "azurerm_api_management_api_operation" "example" {
  operation_id        = "new-test-operation"
  api_name            = "rbac-test-api"
  api_management_name = "<API_MANAGEMENT_NAME>"
  resource_group_name = "<RESOURE_GROUP>"
  display_name        = "New Test Operation"
  method              = "GET"
  url_template        = "/test/operation"
  description         = "This is just a test operation."

  response {
    status_code = 200
  }
}

With these custom access roles, you can give teams narrowly scoped write access to only those specific APIs that this team is responsible for in Azure API Management.

Special thanks to Philip Teilmeier, who has been a great help with this.