Abstract
Post you understand the importanceof API Gateway in modern architectures it is time now to go deep
dive in Azure API Management.
Few of my customers are already on this journey of using
Azure API Management. I have observed a pattern that if you use Azure API
Management then in few moths it automatically becomes a central point of all
your deployments and API Management will be very mission critical to your
entire business. As you grow your footprint on API Management there can be many
unforeseen challenges you face and hence it is better to plan in advance.
With one of my customer they are facing lot of
challenges now with respect to governance and access control of entire API
Management instance in their azure subscription. Let us understand the problem
they are facing and how it can be solved as of today.
Let’s go!
Problem Statement
Basically customer is having around 10 applications [with
approx. 3-4 folks in a team/ application] whose APIs to be published into Azure
API Management. In such cases I always recommend to have following structure as
a best practice which can help to better manage your APIs in Azure API
Management.
[I am using fictitious application names below – ]
#
|
Application Name
|
Azure API Management - Product
recommendation
|
1
|
HR
|
Create a product named as “HR”
|
2
|
Finance
|
Create
a product named as “Finance”
|
3
|
And so on…
|
So essentially you should have at least one dedicated
product in Azure API Management per application. In case of need you can have
two or more products per applications, but at least one azure API Management
product per application is a must. Do not combine two or more applications into
single Azure API Management Product.
So now they have around 10 products and total 50+ people
team working on the same instance of Azure API Management. All of the team
members wanted to publish APIs in products and this where problem starts.
Human nature is of all about building experiences. And
those experience you gain by making mistakes. Making mistakes is not an issue but
it is bad that you don’t work for solving those issues.
Team were accidentally modifying/ deleting/ changing/
creating products and APIs which they were not supposed to touch upon. Some
even re-generated subscription key for APIs or changed the VNET configuration
for API Management without letting others know. Such changes never bring Azure
API Management down; but this led to some horrific abrupt downtimes of their
APIs accessibility through API Management. This was happening because of lack
of governance and access control issues. Let us understand more.
Current available access control RBAC options in Azure API Management and what do we need?
The structure of API Management looks like below –
There are two types of users an API Management has at
high level as shown below –
In order to enable for all the team members to publish
and import API in Azure API Management they will have to be given access as
“Azure API Management Service Contributor”. However providing this access to
any team member provides full access over API Management. There are other roles
defined however few of them are not yet released and there is no role that can
help to restrict access to a particular product in Azure API Management. Refer
to current existent roles in Azure API Management - https://docs.microsoft.com/en-us/azure/api-management/api-management-role-based-access-control.
So in summary we want to achieve below -
- User
from HR app should have access to only HR product in Azure API Management for
any modifications. The other products like Finance and so on should only be
read only.
- User
from Finance app should have access to only Finance product in Azure API
Management for any modifications. The other products like HR and so on should
only be read only.
- Read
only access for entire API Management.
- They should not be able to delete any product/ API or anything from Azure API Management.
Define custom role for Azure API Management using JSON and PowerShell
I have created one API Management instance in my
subscription. Added few APIs. By default you get 2 products – Starter,
Unlimited. These are default and I am not touching them. I create 2 more
products namely “HR” and “Finance” as shown below –
The options “Users, Subscriptions and Groups” in your API Management instance are basically for Developers who wants to consume the API. It is no way related to users who want to publish APIs inside a product. So don’t confuse with these options with what we plan to achieve. Refer to below screenshot –
It is always best way to start with existing definition
of Azure API Management RBAC role and then modify it to suit to your
requirements. Looking at the requirements I have stated above it makes sense to
download the existing JSON of “API Management Reader” role and then modify it.
To download the Reader role details we use Azure PowerShell. Here I assume that
you already have Azure PowerShell installed and you are all set.
First run the login azure account command as shown below
–
Login-AzAccount
After successful login now it is time to download the
API Management Service Reader Role JSON file. Run below command to download the
Azure API Management Reader Role details –
Get-AzRoleDefinition -Name "API
Management Service Reader Role" | ConvertTo-Json | Out-File "Your
Local machine path\APIMProductAdminCustomRole.json"
In above command make sure that you replace the Path
with your choice to create the JSON file. Once you have the JSON file created;
open in VSCode or Visual studio or any of your favorite editor. As the new role
we are creating is custom so make IsCustom field
as true. Similarly the
current Id field is from
Reader role and for our custom role it has to be newly generated. So simply
remove it from JSON. When we create a custom role it will get automatically
create.
In Action section we don’t need our role to make any
deployments in resource group therefore property
Microsoft.Resources/deployments/* is unnecessary. So remove it. At the same time we need our custom role based user to create a support case and should be able to read/ view other services/ resources from the resource group. Therefore keep all the options as shown below -
Microsoft.Resources/deployments/* is unnecessary. So remove it. At the same time we need our custom role based user to create a support case and should be able to read/ view other services/ resources from the resource group. Therefore keep all the options as shown below -
"Microsoft.ApiManagement/service/*/read",
"Microsoft.ApiManagement/service/read",
"Microsoft.Authorization/*/read",
"Microsoft.Insights/alertRules/*",
"Microsoft.ResourceHealth/availabilityStatuses/read",
"Microsoft.Resources/subscriptions/resourceGroups/read",
"Microsoft.Support/*"
This completes Action part. We need more focus on
NoActions part of the JSON and this is crux of our custom role. Therefore add
below options and their description is also provided in comments.
"Microsoft.ApiManagement/service/users/keys/read",
"Microsoft.ApiManagement/service/delete", //no delete of API Management
instance is allowed
"Microsoft.ApiManagement/service/write", //new API Management can't be created
"Microsoft.ApiManagement/service/products/delete", //product can't be deleted
"Microsoft.Resources/deployments/*" //create and
manage resource group deployments
So in summary we are not allowing this custom role to
perform –
- Any
deployments
- Any
type of delete operation on Azure API Management
- Creating
new API Management instance
- Delete
any Azure API Management products
- Reading
of the secret keys is also not allowed.
Now we need to “scope” these permissions at Product
level of Azure API Management. We have created 2 products – HR and Finance in
API Management. Therefore we want HR team only to update/ read HR product, can
view Finance product but should be able to perform any update/ delete operation
on Finance product. So we need to Role based access control for Azure APi
Management at product level –
- . Role named as - API Management Service Product Admin - HR
- Role named as - API Management Service Product Admin – Finance
Essentially we need to create RBAC custom
role dedicated for each of the Azure API Management product.
So for this JSON add name at the top as shown above for
HR. Now we need to assign this custom role to only HR product under Azure API
Management. Therefore let us retrieve the id of HR product from Azure API
Management.
Run below commands to get the ID of a product under
Azure API Management –
#get the id of product in API Management
$apimContext = New-AzApiManagementContext -ResourceGroupName “Resource
group underwhich API Management is present” -ServiceName "Your
API Management instance name"
Get-AzApiManagementProduct -Context $apimContext -Title YourProductName
The output is shown as below for my HR product –
Add this highlighted ID in AssignableScopes section inside your custom
role JSON file as shown below –
This completes building custom role JSON file for Azure
API Management to provide specific product level update access; and restrict
delete/ update/ write operations on other products inside Azure API Management.
Now we need to execute this JSON using PowerShell
further to create the custom role inside Azure subscription.
Create Custom Role using PowerShell
Now our final JSON document can be used to create actual
custom role in Azure API Management. Therefore run below commands in PowerShell
–
#to create new role for the first time
New-AzRoleDefinition -InputFile "Your
local path of choice \ APIMProductAdminCustomRole.json"
This command will automatically generate Id in the
output window. We need to copy and paste this Id inside the JSON. So subsequent
upgrades against the same role can be achieved. The Id generated is as below –
Copy paste this id as below in your JSON file -
To verify the role has ben created successfully run below
command –
#to retrive role definition ID in powershell object
$role = Get-AzRoleDefinition "This name is of your
role as highlighted green in above screenshot"
$role
This completes the custom role creation dedicated for
Azure API Management product named as HR. So depending on the other products
you can create many roles dedicated for each of
the product.
Assign custom role to User
Now that we have custom role already created we need to
assign it to a user. The user can be part of your Azure AD in which your
subscription is present or it can be a Microsoft account [live id/ Hotmail id
etc].
For simplicity I am going to use Microsoft account here.
The process for Azure AD based user remains the same. For assigning the Azure custom
role to user we need its object ID and SignInName [also known as User Principal
Name]. Let us first retrieve the same.
Get-AzADUser -StartsWith "YourUserName"
Below screenshot shows which all records to be captured.
Green box is SignInName and Red box is Object Id or the user –
Then retrieve the complete Id of your Azure API
Management instance which will be used while assigning the access to user.
$apim = Get-AzApiManagement -ResourceGroupName YourResourceGroupName -Name "Your
Azure API Management instance name"
$apim.Id
Record the id displayed in above step.
#assign role at resource scope level means at API Management
level directly
New-AzRoleAssignment -ObjectId "USerObject
Id" -RoleDefinitionName "Reader" -ResourceName "YourAPIManagement
Name" -ResourceType Microsoft.ApiManagement/service -ResourceGroupName "YourResourceGroupName"
New-AzRoleAssignment -SignInName "User SignInName" -RoleDefinitionName "Name
of custom role present in your JSON file" -Scope "Id
of product retrived in earlier steps."
Now this role assignment is not displayed in “Access
Control” option on the portal. As of today I guess custom roles created by you
will not be visible if they are next level than actual resource. For example
Product is present inside Azure API Management. So custom role created at API Management
level may be visible but role created at inner components scope like product is
not visible on Azure portal as of today.
So verify if the role assignment is completed or not by
running below command –
#to check level of access for a user on API Management use
below powershell - custom roles will not be visible on the portal
Get-AzRoleAssignment -ObjectId ObjectId of your user
Verifying the role assignment at product level of Azure API Management
Login to azure portal with the user who has access to HR
[or your respective product] product. After login API Management instance
should be visible. When we open the products all products should also be
visible. However if we try to delete/ update any other products than assigned
one then we should get error similar to below –
Conclusion
And that’s it! Hope this article has given you how can
you control Role based access control in Azure API Management at deep level.
Download the final PowerShell code and JSON I used in above
article from Github here – https://github.com/kunalchandratre1/AzureAPIManagementCustomRoleAtProductLevel
Happy RBACing!!A humble request!
Internet is creating a lot of digital garbage. If you feel this a quality blog and someone will definitely get benefitted, don't hesitate to hit share button present below. Your one share will save many precious hours of a developer. Thank you.
Can you use Azure Ad to create User's ACL and use custom policy to validate client before fwd to the endpoint.
ReplyDeleteYes, use Validate JWT policy.
DeleteCan we have assignable scope at product? so that role can be assigned for all products? User can do every thing inside the product only?
ReplyDeleteHi Sanganak, I can see how this works for products. APIs however aren't owned by products, so different business units would still be able to modify each others apis. Is there a way around this?
ReplyDelete