Service principals with credentials
Do you need to create a Partner Admin Link for a service principal? And it has eligible RBAC role assignments? Can you authenticate using its secret or certificate? If so, follow this guide.
Table of Contents
Introduction brief
This page assumes that you are looking at an existing service principal that
- has Azure RBAC role assignments with PEC eligible roles, and
- you are allowed to use its secret or certificate for authentication.
If you have a service principal or managed identity that you are using in a CI/CD pipeline then visit the CI/CD pipelines & PAL page
If you are intending to “PAL tag” with a new and dedicated Partner Admin Link service principal that exists purely for recognition purposes then go to the PAL tag with a service principal
Note that you cannot create a Partner Admin Link for a service principal using the Azure Portal.
Service principal with secret or cert
Use PowerShell to create the link for a service principal
-
Install the Az.ManagementPartner PowerShell module.
Install-Module -Name Az.ManagementPartner -Repository PSGallery -Force -
Sign in to the customer’s tenant as the service principal.
Using a secret.
$clientSecret = ConvertTo-SecureString "<clientSecret>" -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential("<clientId>", $clientSecret) Connect-AzAccount -ServicePrincipal -TenantId <tenantId> -Credential $credentialOr using a certificate.
Connect-AzAccount -ServicePrincipal -TenantId <tenantId> -CertificateThumbprint <thumbprint> -ApplicationId <clientId> -
Create the Partner Admin Link.
New-AzManagementPartner -PartnerId <partnerId>
The additional AzManagementPartner cmdlets are the same as for managing links for users.
Authenticate
-
Sign in to the customer’s tenant as the service principal.
Using a secret.
az login --service-principal --user "<clientId>" --password "<clientSecret>" --tenant "<tenantId>"Or using a certificate.
az login --service-principal --user "<clientId>" --tenant "<tenantId>" --certificate "<pathToCertificate>"
Use az managementpartner to create the Partner Admin Link
-
Install the Azure CLI’s managementpartner extension.
The az management
az extension add --name "managementpartner"This is a one off task.
-
Create the Partner Admin Link.
az managementpartner create --partner-id "<partnerId>"
The additional Azure CLI commands are the same as for managing links for users.
Alternative using az rest
Alternatively, you can also call the REST API directly using the az rest command. This removes the need to download the extension.
az rest --method put --uri "https://management.azure.com/providers/microsoft.managementpartner/partners/<partnerId>?api-version=2018-02-01" --body '{"partnerId": "<partnerId>"}'
Use the REST API to create the link for a system assigned managed identity
The example here is for a system assigned managed identity on an Azure RHEL linux virtual machine, where the token is retrieved via the Instance Metadata Service (IMDS).
⚠️ Note that whilst it is possible to call the REST API directly, the only documentation for the API appears in the azure-rest-api-specs repo. Also, managed identities are not officially supported.
-
Install jq
sudo dnf install jq -yℹ️ You may need to use a different package manager to install jq if on a different linux distribution.
-
Use the Instance Metadata Service to get a token
token=$(curl -sSL -H "Metadata:true" 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' | jq -r .access_token) -
Define the partnerid
partnerId="31415927"⚠️ Set the partnerid variable to your location based Microsoft Partner ID.
-
Create the PAL link
curl --silent \ --header "Authorization: Bearer ${token}" \ --header "Content-Type: application/json" \ --data '{"partnerId": "'${partnerId}'"}' \ --request PUT \ "https://management.azure.com/providers/microsoft.managementpartner/partners/${partnerId}?api-version=2018-02-01"Using the example MPN ID, the JSON payload would be:
{"partnerId": "31415927"}And the uri would be:
"https://management.azure.com/providers/microsoft.managementpartner/partners/31415927?api-version=2018-02-01"
Partner Admin Link should now associate telemetry for all resources under the service principal’s RBAC role assignments, assuming they include a PEC eligible role.
Attestation
I have created a Bash script, pal_attestation.sh, that you are free to use if it helps you to display information about Partner Admin Link. This is useful if you need to copy and paste the output to prove that a link is in place for that customer context. You can copy and paste the output, pipe it through to jq, or redirect to a file.
A few example usages are shown below for displaying
- the core info (for the tenant, the security principal, and the Partner Admin Link)
- the core info, plus direct RBAC role assignments (note the caveats)
- the core info for another objectId and its RBAC role assignments
You first need to authenticate and ensure that you are in the correct customer context.
This Bash command will work in the Cloud Shell, even in the PowerShell experience.
Core info
curl -sSL https://aka.ms/pal/attestation | bash
{
"tenantId": "ac40fc60-2717-4051-a567-c0cd948f0ac9",
"tenantDisplayName": "Contoso",
"tenantDefaultDomain": "contoso.com",
"type": "user",
"displayName": "Richard Cheney",
"userPrincipalName": "richard.cheney@azurecitadel.com",
"appId": null,
"objectId": "74afa9e2-d243-414b-bab2-db8dd242827f",
"partnerAdminLink": "/providers/microsoft.managementpartner/partners/314159",
"partnerName": "Azure Citadel",
"partnerId": "314159"
}
{
"tenantId": "ac40fc60-2717-4051-a567-c0cd948f0ac9",
"tenantDisplayName": null,
"tenantDefaultDomain": null,
"type": "servicePrincipal",
"displayName": "PAL (Partner Admin Link) for Azure Citadel",
"userPrincipalName": null,
"appId": "7b7fe81e-da85-4271-a065-b0a00634ae75",
"objectId": "a52475b0-d310-41ac-a4b1-d1e3161e0127",
"partnerAdminLink": "/providers/microsoft.managementpartner/partners/314159",
"partnerName": "Azure Citadel",
"partnerId": "314159"
}
Extended info with assignments
Note that this uses the resource graph to additionall get the direct RBAC role assignments.
It will not return secondary RBAC role assignments, e.g. via a security group’s role assignment. You will also not see any temporary assignments (e.g. via Privileged Identity Management or the Access Packages in Microsoft Entra ID Governance’s Entitlement Management) unless they are currently active.
curl -sSL https://aka.ms/pal/attestation | bash -s -- --assignments
{
"tenantId": "ac40fc60-2717-4051-a567-c0cd948f0ac9",
"tenantDisplayName": "Contoso",
"tenantDefaultDomain": "contoso.com",
"type": "user",
"displayName": "Richard Cheney",
"userPrincipalName": "richard.cheney@azurecitadel.com",
"appId": null,
"objectId": "74afa9e2-d243-414b-bab2-db8dd242827f",
"partnerAdminLink": "/providers/microsoft.managementpartner/partners/314159",
"partnerName": "Azure Citadel",
"partnerId": "314159",
"assignments": [
{
"scope": "/providers/Microsoft.Management/managementGroups/alz",
"id": "b25e4a12-2d7d-19b0-3de0-0f12895873ed",
"roleName": "Azure Landing Zones Management Group Reader (alz-mgmt)",
"roleType": "Custom"
},
{
"scope": "/subscriptions/a7484f13-d60f-4e5a-a530-fdaade38716a",
"id": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"roleName": "Owner",
"roleType": "BuiltIn"
},
{
"scope": "/subscriptions/a7484f13-d60f-4e5a-a530-fdaade38716a/resourceGroups/terraform/providers/Microsoft.Storage/storageAccounts/terraformfabric562b54eb",
"id": "ba92f5b4-2d11-453d-a403-e96b0029c9fe",
"roleName": "Storage Blob Data Contributor",
"roleType": "BuiltIn"
}
]
}
{
"tenantId": "ac40fc60-2717-4051-a567-c0cd948f0ac9",
"tenantDisplayName": null,
"tenantDefaultDomain": null,
"type": "servicePrincipal",
"displayName": "PAL (Partner Admin Link) for Azure Citadel",
"userPrincipalName": null,
"appId": "7b7fe81e-da85-4271-a065-b0a00634ae75",
"objectId": "a52475b0-d310-41ac-a4b1-d1e3161e0127",
"partnerAdminLink": "/providers/microsoft.managementpartner/partners/314159",
"partnerName": "Azure Citadel",
"partnerId": "314159",
"assignments": [
{
"scope": "/providers/Microsoft.Management/managementGroups/platform",
"id": "cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e",
"roleName": "Support Request Contributor",
"roleType": "BuiltIn"
},
{
"scope": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15",
"id": "cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e",
"roleName": "Support Request Contributor",
"roleType": "BuiltIn"
},
{
"scope": "/subscriptions/a7484f13-d60f-4e5a-a530-fdaade38716a",
"id": "b24988ac-6180-42a0-ab88-20f7382dd24c",
"roleName": "Contributor",
"roleType": "BuiltIn"
}
]
}
Assignment info for another object id
This is useful to display assignments for another user or service principal.
Note that this will not return the Partner Admin Link information, as you must authenticate for the PAL REST API call to work.
curl -sSL https://aka.ms/pal/attestation | bash -s -- --assignments --object-id <object-id>
The script will handle being passed the app ID, or the object ID for the app reg, and will automatically determine the object ID for the service principal. If you do not want to see the stderr warning messages then add 2>/dev/null to the command.
{
"tenantId": "ac40fc60-2717-4051-a567-c0cd948f0ac9",
"tenantDisplayName": "Contoso",
"tenantDefaultDomain": "contoso.com",
"type": "user",
"displayName": "Richard Cheney",
"userPrincipalName": "richard.cheney@azurecitadel.com",
"appId": null,
"objectId": "74afa9e2-d243-414b-bab2-db8dd242827f",
"partnerAdminLink": "Unavailable",
"partnerName": "Unavailable",
"partnerId": "Unavailable",
"assignments": [
{
"scope": "/providers/Microsoft.Management/managementGroups/alz",
"id": "b25e4a12-2d7d-19b0-3de0-0f12895873ed",
"roleName": "Azure Landing Zones Management Group Reader (alz-mgmt)",
"roleType": "Custom"
},
{
"scope": "/subscriptions/a7484f13-d60f-4e5a-a530-fdaade38716a",
"id": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"roleName": "Owner",
"roleType": "BuiltIn"
},
{
"scope": "/subscriptions/a7484f13-d60f-4e5a-a530-fdaade38716a/resourceGroups/terraform/providers/Microsoft.Storage/storageAccounts/terraformfabric562b54eb",
"id": "ba92f5b4-2d11-453d-a403-e96b0029c9fe",
"roleName": "Storage Blob Data Contributor",
"roleType": "BuiltIn"
}
]
}
{
"tenantId": "ac40fc60-2717-4051-a567-c0cd948f0ac9",
"tenantDisplayName": null,
"tenantDefaultDomain": null,
"type": "servicePrincipal",
"displayName": "PAL (Partner Admin Link) for Azure Citadel",
"userPrincipalName": null,
"appId": "7b7fe81e-da85-4271-a065-b0a00634ae75",
"objectId": "a52475b0-d310-41ac-a4b1-d1e3161e0127",
"partnerAdminLink": "Unavailable",
"partnerName": "Unavailable",
"partnerId": "Unavailable",
"assignments": [
{
"scope": "/providers/Microsoft.Management/managementGroups/platform",
"id": "cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e",
"roleName": "Support Request Contributor",
"roleType": "BuiltIn"
},
{
"scope": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15",
"id": "cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e",
"roleName": "Support Request Contributor",
"roleType": "BuiltIn"
},
{
"scope": "/subscriptions/a7484f13-d60f-4e5a-a530-fdaade38716a",
"id": "b24988ac-6180-42a0-ab88-20f7382dd24c",
"roleName": "Contributor",
"roleType": "BuiltIn"
}
]
}