The Perilous Dilemma of RBAC in an Automated World
With the announcement of Role Based Access Control (RBAC) for Azure Key Vault it got me thinking about the dilemma that comes with RBAC controls. If you aren’t familar with Microsoft’s RBAC roles essential there are predefined roles determined by Microsoft that have access to different endpoint functionality within Azure. Alternatively you can define your own custom RBAC role
This article isn’t about the fact that RBAC is out there an how it can easily be used to manage roles. Personally, RBAC is greate tool to leverage access and assign specific roles to perform desired actions.
The dilemma comes into play when we talk about automating and auto provisioning resources within Azure. Since RBAC is a role assignment the assignment of access can be provisioned via ARM or via PowerShell or even Azure CLI.
Take note to assign a role you need to know the specified ‘objectId’. The objectId is how the entity is defined in Azure Active Directory. So to pick on ARM this is how this assignment may look like:
"roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
Take specific note of principalId. This is the Object ID I referred to above. The issue at hand here is there is no discernable way to determine who or what that object ID belongs to.
So when we automate this role provision and place it under a CI/CD environment we are essentially introducing the issue that we can’t for sure confirm what we are provision access for. In addition these role assignments will start to snow ball into conditional statements since majority of the time we aren’t going to assign the same access to resources in dev/test/prod.
Where this really gets even harrier is we can update an id with our own say for ability to manually update app settings in production. We can interject our own ID in a code review in which 9/10 the reviewer will not bother to look up who the ID associated to and we get approved our access to resources we shouldn’t have access to.
Security and Identity Access Management teams (IAM) want to be able to contain control of how Azure access is provisioned; however, RBAC empowers developers and admins to auto provision the necessary access. Thus the dilemna…Do we empower developers to provision access or Should we follow established security protocol?
I don’t think the answer is to preven developers from provision access nor do I think it’s reasonable to have IAM/Security prevent the toolset from being used. It comes down to how organizations want to handle this predictament.
Keep in mind from an auditing perspective in the above scenario we can trace a role assignment to a deployment, a deployment to a release, a release to a PR, a PR to a developer so we can trace this all the way back if it is set up correctly. This solves the audit question on how access was provisioned but now how do we stay informed when role assignments change?
Some ideas might be to have all RBAC assignments under a separate release that requires Security/IAM control, another would be to switch the mentality from one of prevention to reaction on these. Maybe we need to couple RBAC with some Azure Policies that limit the scope a role can be applied to? (i.e. resource vs subscription vs resource group) If we trust our CI/CD process and it fails us then perhaps we can configure alerts in upper environments when new access is provisioned.
Furthermore maybe this is an opportunity to automate our auditing as a whole. If we have the ability to alert when access changes, which we can do with some alerting and PowerShell, then why not script out all access so we can better maintain what access has been provisioned to each resource.
In the end RBAC is a powerful tool; however, we are still in it’s infancy on how to manage it in a CI/CD automated world. There are no sure fire ways on what to do but perhaps we need to start getting creative and determine what is actually required when controlling access.