Missing Microsoft.Azure.Websites service principal? - azure

I’m trying to get a certificate for my App Service I’m deploying from Key Vault using this template (https://github.com/Azure/azure-quickstart-templates/tree/master/webapp-keyvault-ssl). Part of this requires creating a Key Vault access policy which grants the Microsoft.Azure.Websites service principal (ID abfa0a7c-a6b6-4736-8310-5855508787cd) get on the Secrets. This works in my subscription just fine, but wasn’t working in the customer’s subscription. We could run the Set-AzKeyVaultAccessPolicy command referencing the service principal’s ID, and it executed without error, but the access policy does not actually get created. When I did a get-azAdServicePrincipal -DisplayNameBeginsWith ‘Microsoft.Azure.Websites’ nothing is returned. Yet when I look in the audit log for the KeyVault I can see a user with ID abfa0a7c-a6b6-4736-8310-5855508787cd trying to log in, so somewhere this identity must exist(?)
Is there something I need to do to enable/create this default (Microsoft.Azure.Websites) service principal? I checked my MSDN account and see the same behavior, in that this principal is not present.
Can deploy this template in a subscription where the Microsoft.Azure.Websites principal exists, but when the principal does not exist, the template deployment will fail.
#Gets the service principal (missing in problem subscription)
get-azAdServicePrincipal -DisplayNameBeginsWith 'Microsoft.Azure.Websites'
#Sets the keyvault access policy for the built in service principal
set-azKeyVaultAccessPolicy -VaultName keyVaultName -ServicePrincipalName "abfa0a7c-a6b6-4736-8310-5855508787cd" -PermissionsToSecrets get

‘abfa0a7c-a6b6-4736-8310-5855508787cd’ is the Resource Provider service principal name and it remains same for all Azure subscriptions. And its display name in service principal is 'Microsoft Azure App Service', not 'Microsoft.Azure.Websites'.
Try with
Get-AzADServicePrincipal -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd
to see if it exists.
If it doesn't exist, check the resource provider of your subscription.

Related

Access service principal for Microsoft.Azure.WebSites Resource Provider (Microsoft Azure App Service) from Azure pipeline task

I want to create a key vault that will store a TLS certificate. This key vault needs to be accessible from Azure pipeline tasks, which will retrieve the said certificate and bind it to their apps. Microsoft mentions:
By default, 'Microsoft.Azure.WebSites' Resource Provider (RP) doesn't have access to the Key Vault specified in the template hence you need to authorize it by executing the following PowerShell commands before deploying the template:
Login-AzureRmAccount
Set-AzureRmContext -SubscriptionId AZURE_SUBSCRIPTION_ID
Set-AzureRmKeyVaultAccessPolicy -VaultName KEY_VAULT_NAME -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd -PermissionsToSecrets get
This works for my key vault when I do it manually. However, I want to automate this as part of my master pipeline. I've tried defining this task:
- task: AzurePowerShell#5
displayName: 'Set key vault policy'
inputs:
azureSubscription: …
azurePowerShellVersion: 'LatestVersion'
ScriptType: 'InlineScript'
Inline: |
Set-AzKeyVaultAccessPolicy -VaultName … -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd -PermissionsToSecrets get
But it fails:
##[error]Operation returned an invalid status code 'Forbidden'
I've also noticed that this service principal for "Microsoft Azure App Service" isn't even available to my task; the following prints a blank:
$azureAppServicePrincipal = Get-AzADServicePrincipal -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd
Write-Output "azureAppServicePrincipalId = $($azureAppServicePrincipal.Id)"
Is there a way of making this service principal accessible to my pipeline?
When i tested with parameter Set-AzKeyVaultAccessPolicy -ServicePrincipalName other-service-principal. I get the same error.
You can use ObjectId and add the -BypassObjectIdValidation parameter in Set-AzKeyVaultAccessPolicy command as workaround. See the Note on this document.
When using a service principal to grant access policy permissions, you must use the -BypassObjectIdValidation parameter.
Set-AzKeyVaultAccessPolicy -VaultName myvault -ObjectId "ObjectId" -PermissionsToSecrets get -BypassObjectIdValidation
The Object id is the ObjectId resides in Managed application in local directory
You can also use below Az cli command in the Azure CLI task
az keyvault set-policy -n levikeyv --secret-permissions get --object-id "object-id"
For the command Get-AzADServicePrincipal was not returning any results. It is probably
the service principal associated with your ARM connection service donot have the Read Directory Data permission in the Microsoft Grap
You can try go to the Api permissions of your service principal app and add the proper permission. It may require your Admin's consent. See this thread and this for information.
Levi Lu's answer set me on the right track, but I'm adding my own answer to clarify the exact requirements.
To be able to access the service principal for "Microsoft Azure App Service" (abfa0a7c-a6b6-4736-8310-5855508787cd), you need two things:
Your subscription must have the "Microsoft.Web" resource provider registered. This often gets registered automatically when creating a new subscription, but sometimes it doesn't.
The service principal associated with your ARM service connection (under which your pipeline runs) must have the "Directory.Read.All" permission from the Azure Active Directory Graph. Open your Azure DevOps project settings, click "Service Connections", open your service connection, and click "Manage Service Principal". Then go to "API permissions", click "Add a permission", scroll down and click "Azure Active Directory Graph", "Application permissions", and add "Directory.Read.All". Click "Grant admin consent". If this button is greyed out, you need to get an AAD admin to do this step for you.
Importantly, you must pick the "Directory.Read.All" permission from Azure Active Directory Graph, despite this API being marked as legacy and on a deprecation path. Picking the said permission from Microsoft Graph instead will not work. That said, it's not a bad idea to add the permission from both APIs, in case the requirement eventually switches from one to the other. Something else I found bizarre is that the permission, once it has been granted and consumed, continues to work even after it gets revoked. To get the task to fail again (for the sake of testing), I needed to create a new tenant (Azure Active Directory).
With those two in place, you can grant permission for the "Microsoft Azure App Service" service principal to your key vault through this task (substitute $env:keyVaultName accordingly):
- task: AzurePowerShell#5
displayName: 'Grant key vault access to service principal'
inputs:
azureSubscription: '${{ parameters.armConnection }}'
azurePowerShellVersion: 'LatestVersion'
ScriptType: 'InlineScript'
Inline: |
if (!(Get-AzADServicePrincipal -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd)) {
throw "Current account cannot retrieve service principal `"abfa0a7c-a6b6-4736-8310-5855508787cd`" (Microsoft Azure App Service)."
}
Write-Host "Granting access to service principal `"abfa0a7c-a6b6-4736-8310-5855508787cd`" (Microsoft Azure App Service) on vault `"$($env:keyVaultName)`"..."
Set-AzKeyVaultAccessPolicy -VaultName $env:keyVaultName -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd -PermissionsToSecrets Get,List -PermissionsToCertificates Get,List
Update May 2022:
Microsoft seem to have broken this. The Azure Active Directory Graph API is greyed out, despite that Set-AzKeyVaultAccessPolicy still uses it.
The Microsoft CLI team is in the process of migrating from the Azure Active Directory Graph API to the Microsoft Graph API. Until that is released, the best workaround seems to be to give Application administrator permissions to the service principal, as explained in this answer.

Creating Service Principal for Azure CDN is failing with Tenant Permission Error

I'm trying to add Azure CDN as a service account, in order to connect it to KeyVault.
Following the official guide and other suggestions such as Can't add Microsoft.Azure.Cdn service principal to Key Vault access policies
However this command:
New-AzureRmADServicePrincipal -ApplicationId "205478c0-bd83-4e1b-a9d6-db63a3e1e1c8"
is giving me this error:
New-AzureRmADServicePrincipal : When using this permission, the backing application of the service principal being created must in the local tenant.
Even after I've set the context to the correct tenant using Set-AzureRmContext -TenantId xxx.
any help is appreciated!
The error
When using this permission, the backing application of the service principal being created must in the local tenant.
is reported when you don't have sufficient permissions in AAD to add service principal for application defined in different tenant. This is case of e.g. normal user, who does not have any specific Azure Active Directory Role. With Global Administrator or Application Administrator (or possibly other roles) the command would succeed (please note that these are AAD Administrative Roles, not RBAC roles which are used for resources).
The same error could be reported by az cli call to create principal:
az ad sp create --id 205478c0-bd83-4e1b-a9d6-db63a3e1e1c8

Authorization error when assigning role to web app using VSTS

I am trying to assign role to azure web app using VSTS.
New-AzureRmRoleAssignment -ObjectId 976a5114-xxxx-xxxx-xxxx-7403ef25ac29 -RoleDefinitionName "Reader" -Scope "/subscriptions/4364666b-xxxx-xxxx-xxxx-47158904c439/resourceGroups/devt002RG/providers/Microsoft.Storage/storageAccounts/devt002"
Error :
2019-03-26T09:26:16.5246563Z ##[error]The client 'a78361e3-xxxx-xxxx-xxxx-fb0ced07865c' with object id 'a78361e3-xxxx-xxxx-xxxx-fb0ced07865c' does not have authorization to perform action 'Microsoft.Authorization/roleAssignments/write' over scope '/subscriptions/4364666b-xxxx-xxxx-xxxx-47158904c439/resourceGroups/devt002RG/providers/Microsoft.Storage/storageAccounts/devt002/providers/Microsoft.Authorization/roleAssignments/466c9ad5-xxxx-xxxx-xxxx-c0ff4051db14'.
I am the owner on the subscription 4364666b-xxxx-xxxx-xxxx-47158904c439
Note : Working fine when run using cloud shell.
You should have the owner permission of your subscription first, and then login with the service principal through Azure PowerShell. So you can assign the Reader role to your storage account.
I can reappear the error you got and then achieve your purpose. Below is the screenshot of the process:
The error you got:
Get the owner permission of your subscription and then login with the service principal in a new PowerShell session:
Assign the Reader role to your storage account:
There is an exception but the role has created.
Note: When you are in Azure Cloud Shell, then you already login the Azure with your Azure account in default, not the service principal.

How do I Choose which AAD you Create the Service Principal in?

I can't find any documentation on how to choose which AAD to create the service principal in. Basically, I can't find out if there is even a way to add the SP to the local AAD.
So we have a default Global AD which covers all of our enrollment and below that all subscriptions. I'm using Powershell derived from the many many examples on the net to create a SP in the default AD. Then I permission that SP against the subscription it is going to be working in.
At this point I've run into the following problem.
I'm rolling out a Key Vault, this works.
New-AzureRmKeyVault -VaultName $VaultName -EnabledForDeployment -EnabledForTemplateDeployment -ResourceGroupName $ResourceGroupName -Location $Location -Verbose
I need to add the first secret into it as part of the deployment. This bit fails because the SP doesn't have access to the KV.
# Set-AzureRmKeyVaultAccessPolicy -VaultName $VaultName -ResourceGroupName $ResourceGroupName -PermissionsToSecrets get,set -ServicePrincipalName $ServicePrincipalName
This is the result of that command.
Set-AzureRmKeyVaultAccessPolicy : Cannot find the Active Directory object
'Service-Principal-Name' in tenant '6166a717-xxxx-xxxxx-b0e8-6b7288c1f7ec'.
Please make sure that the user or application service principal you are
authorizing is registered in the current subscription's Azure Active
directory.
Reading into this, its not possible to set the Global AD Service Principal to have get/set on the local Keyvault. it would have to be a local Service Principal. However, we dont have one of them and nowhere can I work out how to create one of them.
Anyone else feeling this pain and know how to resolve it?
In the settings section of the old portal (manage.windowsazure.com), you will find a list of all subscriptions. The fourth column (Directory) shows the default directory that is associated with each subscription. No matter what, you will have to create the Service Principal in the Directory that is associated with that particular subscription. Please check this link to understand the relationship between Subscriptions and AAD.

Using Azure KeyVault, cannot find object in Azure Active Directory tenant

Using Azure KeyVault I have set up a ResourceGroup, KeyVault and Key by following this guide:
https://azure.microsoft.com/en-gb/documentation/articles/key-vault-get-started/
I have set up the application client in Active Directory. However when I try to use:
Set-AzureKeyVaultAccessPolicy
I get the following error when granting permissions to the Service Principal account:
"Cannot find the Active Directory object 'clientId' in tenant 'tenantId'. Please make sure that the user of application service principal you are authorizing is registered in the current subscription's Azure Active directory."
The clientId is correct as this was copied from the application configuration page in the portal. The tenant Id is the tenant ID for the current subscription.. but not for the active directory.
The problem seems to be that the tenant ID for the Active Directory is different to the tenant ID for the subscription I'm using. How do I change the tenant ID of my Active Directory in the Azure Portal to match the subscription tenant ID?
The tenant ID refers to the unique identifier of the Azure AD directory. Every Azure subscription is associated with a directory (or "tenant").
It sounds like you've created the application in a different directory from the directory that is associated with the Azure subscription in which you've created the Key Vault.
When registering the applications, when you go to the "Active Directory" section of the Azure Management portal, be sure to choose the same directory as the one to which you subscription (the subscription where you created the Azure Key Vault) is associated.
There is two things wrong with the documentation you can find on https://learn.microsoft.com/en-us/azure/key-vault/key-vault-get-started#a-idauthorizeaauthorize-the-application-to-use-the-key-or-secret
1) The -ServicePrincipalName parameter should NOT (as the example in the link suggests) be the Client Id (Guid), but the AD Apps Identifier Uri (you can find that on the properties page of the AD App)
2) If you did not create your AD App using the portal, but created it from Powershell Azure Resource Manager scripts, there is no Service Principal created for your AD App yet. You have to do this using the New-AzureRmADServicePrincipal cmdlet, before running Set-AzureRmKeyVaultAccessPolicy.
In total, you should then have
$app = New-AzureRmADApplication -DisplayName "Test" -HomePage "http://myapp.contoso.com" -IdentifierUris "http://myapp.contoso.com" -Password "password"
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId
Set-AzureRmKeyVaultAccessPolicy -VaultName "vaultname" -ServicePrincipalName "http://myapp.contoso.com" -PermissionsToSecrets Get
You can also find the discussion regarind this on https://social.msdn.microsoft.com/Forums/azure/en-US/ae8d2782-ecf7-4d35-9859-d4455e65a668/setazurermkeyvaultaccesspolicy-cannot-find-the-active-directory-object-in-tenant-?forum=AzureKeyVault

Resources