Доступ к субъекту службы для поставщика ресурсов Microsoft.Azure.WebSites (служба приложений Microsoft Azure) из задачи конвейера Azure

Я хочу создать хранилище ключей, в котором будет храниться сертификат TLS. Это хранилище ключей должно быть доступно из задач конвейера Azure, которые будут извлекать указанный сертификат и связывать его со своими приложениями. Microsoft упоминает:

По умолчанию поставщик ресурсов (RP) Microsoft.Azure.WebSites не имеет доступа к хранилищу ключей, указанному в шаблоне, поэтому вам необходимо авторизовать его, выполнив следующие команды PowerShell перед развертыванием шаблона:

Login-AzureRmAccount
Set-AzureRmContext -SubscriptionId AZURE_SUBSCRIPTION_ID
Set-AzureRmKeyVaultAccessPolicy -VaultName KEY_VAULT_NAME -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd -PermissionsToSecrets get

Это работает для моего хранилища ключей, когда я делаю это вручную. Однако я хочу автоматизировать это как часть моего основного конвейера. Я пробовал определить эту задачу:

- 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

Но не получается:

##[error]Operation returned an invalid status code 'Forbidden'

Я также заметил, что этот принципал службы приложений Microsoft Azure даже недоступен для моей задачи; следующее печатает пробел:

 $azureAppServicePrincipal = Get-AzADServicePrincipal -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd
 Write-Output "azureAppServicePrincipalId = $($azureAppServicePrincipal.Id)"

Есть ли способ сделать этот принципал службы доступным для моего конвейера?


person 14207973    schedule 14.10.2020    source источник
comment
Можете ли вы запустить Set key vault policy, не отдавая -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd?   -  person Krzysztof Madej    schedule 14.10.2020
comment
Да, это работает, если я предоставлю идентификатор объекта или использую собственный принципал службы конвейера: Set-AzKeyVaultAccessPolicy -VaultName … -ServicePrincipalName (Get-AzContext).Account.Id -PermissionsToCertificates get   -  person 14207973    schedule 14.10.2020
comment
Решает ли это вашу проблему? Или вам нужно что-то еще?   -  person Krzysztof Madej    schedule 14.10.2020
comment
Я могу установить политику доступа для субъекта-службы, связанного с моей службой подключения ARM, но не для субъекта-службы, связанного с поставщиком ресурсов (RP) Microsoft.Azure.WebSites, что мне и нужно. Я начинаю подозревать, что это проблема с разрешениями AD.   -  person 14207973    schedule 15.10.2020


Ответы (2)


Когда я тестировал с параметром Set-AzKeyVaultAccessPolicy -ServicePrincipalName other-service-principal. Я получаю ту же ошибку.

Вы можете использовать ObjectId и добавить параметр -BypassObjectIdValidation в команду Set-AzKeyVaultAccessPolicy в качестве обходного пути. См. Примечание к t его документ.

При использовании субъекта-службы для предоставления разрешений политики доступа необходимо использовать параметр -BypassObjectIdValidation.

Set-AzKeyVaultAccessPolicy -VaultName myvault -ObjectId "ObjectId" -PermissionsToSecrets get -BypassObjectIdValidation 

Идентификатор объекта - это идентификатор объекта, который находится в Managed application in local directory

введите описание изображения здесь

Вы также можете использовать команду ниже Az cli в задаче Azure CLI.

az keyvault set-policy -n levikeyv --secret-permissions get --object-id "object-id"

Команда Get-AzADServicePrincipal не вернула никаких результатов. Вероятно, субъект службы, связанный с вашей службой подключения ARM, не имеет Read Directory Data разрешения в Microsoft Grap.

Вы можете попробовать перейти к разрешениям Api своего основного приложения-службы и добавить соответствующее разрешение. Для этого может потребоваться согласие вашего администратора. См. эту ветку и this для информации.

введите описание изображения здесь

person Levi Lu-MSFT    schedule 15.10.2020
comment
Спасибо за подробный ответ! Я рассматривал подход -ObjectId, но считаю, что такие идентификаторы объектов специфичны для моего клиента и не будут переноситься, в отличие от -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd. Я подозреваю, что подход -ServicePrincipalName сработает, если я добавлю эти разрешения; позвольте мне попробовать это. - person 14207973; 15.10.2020
comment
Да, это сработало; благодарю вас! Однако мне нужно было больше разрешений, чем просто Microsoft Graph ›Чтение данных каталога. Я все еще экспериментирую с минимальным набором, который требуется; Я отчитаюсь, когда определю это. - person 14207973; 16.10.2020
comment
@ User14207973 - какое дополнительное разрешение вы установили, я столкнулся с той же проблемой - person John; 16.10.2020
comment
@John: Мне нужно разрешение Directory.Read.All из Azure Active Directory Graph, а не из Microsoft Graph. Подробнее см. В моем ответе. - person 14207973; 17.10.2020

Ответ Леви Лу направил меня на правильный путь, но я добавляю свой собственный ответ, чтобы прояснить точные требования.

Чтобы иметь доступ к принципалу службы для Microsoft Azure App Service (abfa0a7c-a6b6-4736-8310-5855508787cd), вам потребуются две вещи:

  1. В вашей подписке должен быть зарегистрирован поставщик ресурсов Microsoft.Web. Это часто регистрируется автоматически при создании новой подписки, но иногда это не так.

Microsoft.Web


  1. Субъект службы, связанный с вашим подключением к службе ARM (под которым работает конвейер), должен иметь разрешение Directory.Read.All из Azure Active Directory Graph. Откройте настройки проекта Azure DevOps, щелкните Подключения к службе, откройте подключение к службе и щелкните Управление субъектом-службой. Затем перейдите к разрешениям API, щелкните Добавить разрешение, прокрутите вниз и щелкните Azure Active Directory Graph, Разрешения приложений и добавьте Directory.Read.All. Щелкните Предоставить согласие администратора. Если эта кнопка неактивна, вам нужно, чтобы администратор AAD выполнил этот шаг за вас.

Управление субъектом службы


Добавить разрешение


Directory.Read.All


Предоставить согласие


Согласие предоставлено


Важно отметить, что вы должны выбрать разрешение Directory.Read.All из Azure Active Directory Graph, несмотря на то, что этот API отмечен как устаревший и находится в пути устаревания. Вместо этого выбор указанного разрешения в Microsoft Graph не сработает. Тем не менее, неплохо добавить разрешение от обоих API, на случай, если требование в конечном итоге переключится с одного на другой. Еще мне показалось странным то, что разрешение после того, как оно было предоставлено и использовано, продолжает работать даже после того, как оно отозвано. Чтобы задача снова перестала работать (для тестирования), мне нужно было создать новый клиент (Azure Active Directory).

Имея эти два места, вы можете предоставить разрешение для субъекта-службы приложений Microsoft Azure вашему хранилищу ключей с помощью этой задачи (замените $env:keyVaultName соответственно):

- 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
person 14207973    schedule 17.10.2020