title: Databricks API 2.0 - create secret scope in powershell using service principal credentials
body: <p>I am trying to create a key vault backed secret scope in Azure databricks using a powershell script that runs during Azure DevOps deployment. It works fine when I run locally using my own credentials but I get an error when I try to run it using the service principal credentials.</p>
  <p>The problem I'm having is similar to but not exactly the same as <a href="https://stackoverflow.com/questions/64893403/databricks-api-2-0-cant-create-keyvault-secrets-scopes-using-spn-credentials">this previous post</a>.</p>
  <p>Here is my script:</p>
  <pre><code>[CmdletBinding()]
  Param(
      $azureADDatabricksAccessToken = $env:AZUREADDATABRICKSACCESSTOKEN,
      $azureManagementAccessToken = $env:AZUREMANAGEMENTACCESSTOKEN,
      $workspaceResourceId,
      $subscription,
      $resourceGroup,
      $keyVault,
      $workspaceUrl,
      $scope
  )
  $headers = @{ 
  &quot;Authorization&quot; = &quot;Bearer $azureADDatabricksAccessToken&quot;;
  &quot;X-Databricks-Azure-SP-Management-Token&quot; = $azureManagementAccessToken;
  &quot;X-Databricks-Azure-Workspace-Resource-Id&quot; = $workspaceResourceId;
  }
  
  [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
  $scopes = (Invoke-RestMethod -Uri &quot;https://$workspaceUrl/api/2.0/secrets/scopes/list&quot; -Method Get -Headers $headers).scopes
  $exists = ($scopes | Where-Object {$_.name -eq $scope}).Count -gt 0
  if($exists){
      Write-Host &quot;Secret scope found&quot;;
  }
  else{
      Write-Host &quot;Creating new secret scope&quot;;
      
      $body = @{
       &quot;scope&quot; = &quot;$scope&quot;;
       &quot;scope_backend_type&quot; = &quot;AZURE_KEYVAULT&quot;;
       &quot;backend_azure_keyvault&quot; =
       @{
         &quot;resource_id&quot; = &quot;/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.KeyVault/vaults/$keyVault&quot;;
         &quot;dns_name&quot; = &quot;https://$keyVault.vault.azure.net/&quot;;
       };
       &quot;initial_manage_principal&quot; = &quot;users&quot;;
      }
  
      [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
      Invoke-RestMethod -Uri &quot;https://$workspaceUrl/api/2.0/secrets/scopes/create&quot; -Method Post -Headers $headers -Body (ConvertTo-Json $body)
  }
  </code></pre>
  <p>I get my access tokens like this:</p>
  <pre><code>$azureADDatabricksAccessToken = (az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --resource-type aad-graph | ConvertFrom-Json).accessToken
  $azureManagementAccessToken = (az account get-access-token --resource &quot;https://management.core.windows.net/&quot; | ConvertFrom-Json).accessToken
  </code></pre>
  <p>This works when I log in using <code>az login -t XXXX</code> but it fails when run as a service principal using <code>az login --service-principal -u XXXX -p XXXX --tenant XXXX</code>.</p>
  <p>The error message I get is:</p>
  <pre><code>error_code&quot;:&quot;CUSTOMER_UNAUTHORIZED&quot;,&quot;message&quot;:&quot;Unable to grant read/list permission to Databricks service principal to KeyVault 
  'XXXXX': key not found: https://graph.windows.net/
  </code></pre>
  <p>Is there some other access token header I need to add for <code>graph.windows.net</code> when running as a service principal?</p>