[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New-AzureRmADApplication - Creating new SPNs from existing SPN fails #3215

Open
Hoppy7 opened this issue Nov 21, 2016 · 23 comments
Open

New-AzureRmADApplication - Creating new SPNs from existing SPN fails #3215

Hoppy7 opened this issue Nov 21, 2016 · 23 comments
Assignees
Labels
customer-reported Resource Authorization AzRole* in Az.Resources Service Attention This issue is responsible by Azure service team.

Comments

@Hoppy7
Copy link
Hoppy7 commented Nov 21, 2016

Cmdlet(s)

New-AzureRmADApplication

PowerShell Version

5.1.14393.206

Module Version

3.1.0

OS Version

10.0.14393.206

Description

I'd like to use one "master" SPN to be able to create new SPNs and rotate expiring SPN keys through automation. The master SPN is an owner of the subscription it's running from and has been granted all permissions to the AAD application. It is not able to create new SPNs or rotate expiring keys.

I've also tried authenticating as the SPN in which we would like to generate a new key for, and then attempt to generate a new key. This route also fails. I would think the SPN should be able to generate a new key for itself?

Is either of these scenarios possible running from a SPN? I can create new SPNs and generate new keys using my own credentials just fine.

Error:
New-AzureRmADApplication : Resource not found for the segment 'me'.

Debug Output

PS C:\Users\v-rohopk> $DebugPreference="Continue"
PS C:\Users\v-rohopk>     [string]$SPNname = "<SPN_Name>"
PS C:\Users\v-rohopk>     [string]$SPNurl = "<SPN_URL>"
PS C:\Users\v-rohopk>     [string]$SPNage = "2"
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> #############################################################
PS C:\Users\v-rohopk> ######################### Variables #########################
PS C:\Users\v-rohopk> #############################################################
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> $SPNsubid = '<SPN_SubID>'
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> # Azure Key Vault
PS C:\Users\v-rohopk> $KeyVaultName = "<Keyvault_Name>"
PS C:\Users\v-rohopk> $KeyVaultSubID = '<KeyVault_SubID>'
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> #############################################################
PS C:\Users\v-rohopk> ####################### End Variables #######################
PS C:\Users\v-rohopk> #############################################################
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> Function Generate-RandomPassword {
>>
>>     param (
>>     [string]$LowerCaseCount = "5",
>>     [string]$UpperCaseCount = "10",
>>     [string]$NumberCount = "10"
>>     )
>>
>>     $UpperAlphabet = [char[]]([char]'A'..[char]'Z')
>>     $LowerAlphabet = [char[]]([char]'a'..[char]'z')
>>     $NumberAlphabet = [char[]]([char]'0'..[char]'9')
>>
>>     $Lowercase = Get-Random -InputObject $LowerAlphabet -Count $LowerCaseCount
>>     $Uppercase = Get-Random -InputObject $UpperAlphabet -Count $UpperCaseCount
>>     $Numbers = Get-Random -InputObject $NumberAlphabet -Count $NumberCount
>>
>>     $foo
>>     $foo += $Lowercase
>>     $foo += $Uppercase
>>     $foo += $Numbers
>>
>>     $RandomPassword = Get-Random $foo -Count 25
>>     [string]$Password = ""
>>     $RandomPassword | % {
>>     $Password += $_
>>     }
>>
>>     Return $Password
>>
>> } # End Generate-RandomPassword
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> # Validate Params
PS C:\Users\v-rohopk> If ($SPNname -eq $null) {
>>
>>     Throw "Please specify a SPNname."
>> }
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> If ($SPNurl -eq $null) {
>>
>>     Throw "Please specify a SPNurl."
>> }
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> If ($SPNage -ne "1" -and $SPNage -ne "2") {
>>
>>     Throw "Please specify an SPN age limit of 1 or 2 years."
>> }
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> Select-AzureRmSubscription -SubscriptionId $SPNsubid
DEBUG: 11:58:02 AM - SetAzureRMContextCommand begin processing with ParameterSet 'SubscriptionId'.
DEBUG: 11:58:02 AM - using account id '<SPN_AppID>'...
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:02:  - TokenCache: Deserialized 1 items to token cache.
DEBUG: [Common.Authentication]: Authenticating using configuration values: Domain: 'Common', Endpoint: 'https://login.microsoftonline.com/', ClientId: '<Client_ID>', ClientRedirect:
'urn:ietf:wg:oauth:2.0:oob', ResourceClientUri: 'https://management.core.windows.net/', ValidateAuthrity: 'True'
DEBUG: [Common.Authentication]: Renewing token using AppId: '<SPN_AppID>', AdalConfiguration with ADDomain: 'Common', AdEndpoint: 'https://login.microsoftonline.com/', ClientId:
'<Client_ID>', RedirectUri: 'urn:ietf:wg:oauth:2.0:oob'
DEBUG: [Common.Authentication]: Authenticating using configuration values: Domain: '<Tenant_ID>', Endpoint: 'https://login.microsoftonline.com/', ClientId:
'<Client_ID>', ClientRedirect: 'urn:ietf:wg:oauth:2.0:oob', ResourceClientUri: 'https://management.core.windows.net/', ValidateAuthrity: 'True'
DEBUG: [Common.Authentication]: Renewing token using AppId: '<SPN_AppID>', AdalConfiguration with ADDomain: '<Tenant_ID>', AdEndpoint:
'https://login.microsoftonline.com/', ClientId: '<Client_ID>', RedirectUri: 'urn:ietf:wg:oauth:2.0:oob'
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:02: <ID> - AcquireTokenHandlerBase: === Token Acquisition started:
 Authority: https://login.microsoftonline.com/<Tenant_ID>/
 Resource: https://management.core.windows.net/
 ClientId: <SPN_AppID>
 CacheType: Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache (1 items)
 Authentication Target: Client

DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 :
DEBUG: 11/21/2016 19:58:02: <ID> - TokenCache: Looking up cache for a token...
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:02: <ID> - TokenCache: An item matching the requested resource was found in the cache
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 :
DEBUG: 11/21/2016 19:58:02: <ID> - TokenCache: 59.4337402116667 minutes left until token in cache expires
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:02: <ID> - TokenCache: A matching item (access token or refresh token or both) was found in the cache
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:02: <ID> - AcquireTokenHandlerBase: === Token Acquisition finished successfully. An access token was retuned:
 Access Token Hash: <Token_Hash>
 Refresh Token Hash: [No Refresh Token]
 Expiration Time: 11/21/2016 20:57:28 +00:00
 User Hash: null

DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
GET

Absolute Uri:
https://management.azure.com/subscriptions?api-version=2014-04-01-preview

Headers:

Body:


DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
OK

Headers:
Pragma                        : no-cache
x-ms-ratelimit-remaining-tenant-reads: 14999
x-ms-request-id               : <Request_ID>
x-ms-correlation-request-id   : <Request_ID>
x-ms-routing-request-id       : WESTUS2:20161121T195803Z:<Request_ID>
Strict-Transport-Security     : max-age=31536000; includeSubDomains
Cache-Control                 : no-cache
Date                          : Mon, 21 Nov 2016 19:58:03 GMT

Body:
{
  "value": [
    {
      "id": "/subscriptions/<SPN_SubID>",
      "subscriptionId": "<SPN_SubID>",
      "displayName": "<Sub_Name>",
      "state": "Enabled",
      "subscriptionPolicies": {
        "locationPlacementId": "Internal_2014-09-01",
        "quotaId": "Internal_2014-09-01",
        "spendingLimit": "Off"
      }
    }
  ]
}

DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:03:  - TokenCache: Serializing token cache with 1 items.


Environment           : AzureCloud
Account               : <SPN_AppID>
TenantId              : <Tenant_ID>
SubscriptionId        : <SPN_SubID>
SubscriptionName      : <Sub_Name>
CurrentStorageAccount :

DEBUG: AzureQoSEvent: CommandName - Set-AzureRmContext; IsSuccess - True; Duration - 00:00:01.1378935; Exception - ;
DEBUG: Finish sending metric.
DEBUG: 11:58:04 AM - SetAzureRMContextCommand end processing.
DEBUG: 11:58:04 AM - SetAzureRMContextCommand end processing.


PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> # Generate Random Password for AAD App
PS C:\Users\v-rohopk> [string]$GeneratedPassword = Generate-RandomPassword
PS C:\Users\v-rohopk> $Password = $GeneratedPassword.trim()
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> # Create Start and End Dates
PS C:\Users\v-rohopk> $StartDate = Get-Date -f MM/dd/yyyy
PS C:\Users\v-rohopk> $EndDate = (Get-Date).AddYears($SPNage).ToString("MM/dd/yyyy")
PS C:\Users\v-rohopk>
PS C:\Users\v-rohopk> Try {
>>
>>     # Create AAD App
>>     $App = New-AzureRmADApplication -DisplayName $SPNname -HomePage $SPNurl -IdentifierUris $SPNurl -Password $Password -StartDate $StartDate -EndDate $EndDate
>>     Start-Sleep -Seconds 30
>>     New-AzureRmADServicePrincipal -ApplicationId $App.ApplicationId
>>     $GUID = $App.ApplicationId.Guid
>>     Start-Sleep -Seconds 30
>>     New-AzureRmRoleAssignment -RoleDefinitionName Owner -ServicePrincipalName $GUID
>> } Catch [Exception] {
>>
>>     $Exception = $_
>>
>> } Finally {
>>
>>     If ($Exception -eq $null) {
>>
>>         # Add SPN to KeyVault
>>         Select-AzureRmSubscription -SubscriptionId $KeyVaultSubID
>>         $Tags = @{"AccountType"="SPN";"SPNType"="Key";"KeyDuration"="$SPNage";"ExpirationDate"="$EndDate";"URL"="$SPNurl";"AppID"="$GUID"}
>>
>>         $SecretValue = ConvertTo-SecureString $Password -AsPlainText –Force
>>         $Secret = Set-AzureKeyVaultSecret -VaultName $KeyVaultName -Name $SPNname -SecretValue $SecretValue -Tags $Tags
>>     }
>> }
DEBUG: 11:58:06 AM - NewAzureADApplicationCommand begin processing with ParameterSet 'ApplicationWithPasswordPlainParameterSet'.
DEBUG: 11:58:06 AM - using account id '<SPN_AppID>'...
DEBUG: [Common.Authentication]: Authenticating using Account: '<SPN_AppID>', environment: 'AzureCloud', tenant: '<Tenant_ID>'
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:06:  - TokenCache: Deserialized 1 items to token cache.
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:06: <ID> - AcquireTokenHandlerBase: === Token Acquisition started:
 Authority: https://login.microsoftonline.com/<Tenant_ID>/
 Resource: https://graph.windows.net/
 ClientId: <SPN_AppID>
 CacheType: Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache (1 items)
 Authentication Target: Client

DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 :
DEBUG: 11/21/2016 19:58:06: <ID> - TokenCache: Looking up cache for a token...
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:06: <ID> - TokenCache: No matching token was found in the cache
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 :
DEBUG: 11/21/2016 19:58:06: <ID> - TokenCache: Storing token in the cache...
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 :
DEBUG: 11/21/2016 19:58:06: <ID> - TokenCache: An item was stored in the cache
DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:06: <ID> - AcquireTokenHandlerBase: === Token Acquisition finished successfully. An access token was retuned:
 Access Token Hash: <Token_Hash>
 Refresh Token Hash: [No Refresh Token]
 Expiration Time: 11/21/2016 20:58:05 +00:00
 User Hash: null

DEBUG: Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 :
DEBUG: 11/21/2016 19:58:06:  - TokenCache: Serializing token cache with 2 items.
DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
POST

Absolute Uri:
https://graph.windows.net/<Tenant_ID>/applications?api-version=1.6

Headers:
x-ms-client-request-id        : <Request_ID>
accept-language               : en-US

Body:
{
  "availableToOtherTenants": false,
  "displayName": "<SPN_Name>",
  "homepage": "<SPN_URL>",
  "identifierUris": [
    "<SPN_URL>"
  ],
  "passwordCredentials": [
    {
      "startDate": "2016-11-21T00:00:00Z",
      "endDate": "2018-11-21T00:00:00Z",
      "keyId": "<Key_ID>",
      "value": "<Value>"
    }
  ]
}

DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
Forbidden

Headers:
Pragma                        : no-cache
ocp-aad-diagnostics-server-name: <Server_Name>
request-id                    : <Request_ID>
client-request-id             : <Client_Request_ID>
x-ms-dirapi-data-contract-version: 1.6
ocp-aad-session-key           : <Session_Key>
X-Content-Type-Options        : nosniff
DataServiceVersion            : 3.0;
Access-Control-Allow-Origin   : *
Duration                      : 362070
Cache-Control                 : no-cache
Server                        : Microsoft-IIS/8.5
X-AspNet-Version              : 4.0.30319
X-Powered-By                  : ASP.NET,ASP.NET
Date                          : Mon, 21 Nov 2016 19:58:05 GMT

Body:
{
  "odata.error": {
    "code": "Authorization_RequestDenied",
    "message": {
      "lang": "en",
      "value": "Insufficient privileges to complete the operation."
    }
  }
}

DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
GET

Absolute Uri:
https://graph.windows.net/<Tenant_ID>/me?api-version=1.6

Headers:
x-ms-client-request-id        : <Request_ID>
accept-language               : en-US

Body:


DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
NotFound

Headers:
ocp-aad-diagnostics-server-name: <Server_Name>
request-id                    : <Request_ID>
client-request-id             : <Client_Request_ID>
x-ms-dirapi-data-contract-version: 1.6
ocp-aad-session-key           : <Session_Key>
X-Content-Type-Options        : nosniff
DataServiceVersion            : 3.0;
Strict-Transport-Security     : max-age=31536000; includeSubDomains
Access-Control-Allow-Origin   : *
Duration                      : 1275144
Cache-Control                 : private
Server                        : Microsoft-IIS/8.5
X-AspNet-Version              : 4.0.30319
X-Powered-By                  : ASP.NET,ASP.NET
Date                          : Mon, 21 Nov 2016 19:58:07 GMT

Body:
{
  "odata.error": {
    "code": "Request_ResourceNotFound",
    "message": {
      "lang": "en",
      "value": "Resource not found for the segment 'me'."
    }
  }
}

DEBUG: Caught exception, type: Microsoft.Azure.Graph.RBAC.Models.GraphErrorException
DEBUG: Received exception from graph. ErrorCode: Request_ResourceNotFound, Message: Resource not found for the segment 'me'.
New-AzureRmADApplication : Resource not found for the segment 'me'.
At line:4 char:12
+     $App = New-AzureRmADApplication -DisplayName $SPNname -HomePage $ ...
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-AzureRmADApplication], Exception
    + FullyQualifiedErrorId : Request_ResourceNotFound,Microsoft.Azure.Commands.ActiveDirectory.NewAzureADApplicationCommand

DEBUG: AzureQoSEvent: CommandName - New-AzureRmADApplication; IsSuccess - False; Duration - 00:00:01.2460539; Exception - System.Exception: Resource not found for the segment 'me'.;
DEBUG: Finish sending metric.
DEBUG: 11:58:07 AM - NewAzureADApplicationCommand end processing.
DEBUG: 11:58:07 AM - NewAzureADApplicationCommand end processing.

Script/Steps for Reproduction

[string]$SPNname = "<SPN_Name>"
[string]$SPNurl = "<SPN_URL>"
[string]$SPNage = "<Key_Duration>"


#############################################################
######################### Variables #########################
#############################################################

$SPNsubid = '<SPN_SubID>'

# Azure Key Vault
$KeyVaultName = "<KeyVault_Name>"
$KeyVaultSubID = '<KeyVault_SubID>'

#############################################################
####################### End Variables #######################
#############################################################

Function Generate-RandomPassword {

    param (
    [string]$LowerCaseCount = "5",
    [string]$UpperCaseCount = "10",
    [string]$NumberCount = "10"
    )

    $UpperAlphabet = [char[]]([char]'A'..[char]'Z')
    $LowerAlphabet = [char[]]([char]'a'..[char]'z')
    $NumberAlphabet = [char[]]([char]'0'..[char]'9')

    $Lowercase = Get-Random -InputObject $LowerAlphabet -Count $LowerCaseCount
    $Uppercase = Get-Random -InputObject $UpperAlphabet -Count $UpperCaseCount
    $Numbers = Get-Random -InputObject $NumberAlphabet -Count $NumberCount

    $foo
    $foo += $Lowercase 
    $foo += $Uppercase
    $foo += $Numbers

    $RandomPassword = Get-Random $foo -Count 25
    [string]$Password = ""
    $RandomPassword | % {
    $Password += $_
    }

    Return $Password

} # End Generate-RandomPassword


# Validate Params
If ($SPNname -eq $null) {
    
    Throw "Please specify a SPNname."
}

If ($SPNurl -eq $null) {

    Throw "Please specify a SPNurl."
}

If ($SPNage -ne "1" -and $SPNage -ne "2") {
    
    Throw "Please specify an SPN age limit of 1 or 2 years."
}

Select-AzureRmSubscription -SubscriptionId $SPNsubid

# Generate Random Password for AAD App
[string]$GeneratedPassword = Generate-RandomPassword
$Password = $GeneratedPassword.trim()

# Create Start and End Dates
$StartDate = Get-Date -f MM/dd/yyyy
$EndDate = (Get-Date).AddYears($SPNage).ToString("MM/dd/yyyy")

Try {

    # Create AAD App
    $App = New-AzureRmADApplication -DisplayName $SPNname -HomePage $SPNurl -IdentifierUris $SPNurl -Password $Password -StartDate $StartDate -EndDate $EndDate
    Start-Sleep -Seconds 30
    New-AzureRmADServicePrincipal -ApplicationId $App.ApplicationId
    $GUID = $App.ApplicationId.Guid
    Start-Sleep -Seconds 30
    New-AzureRmRoleAssignment -RoleDefinitionName Owner -ServicePrincipalName $GUID
} Catch [Exception] {

    $Exception = $_
} Finally {

    If ($Exception -eq $null) { 
    
        # Add SPN to KeyVault
        Select-AzureRmSubscription -SubscriptionId $KeyVaultSubID
        $Tags = @{"AccountType"="SPN";"SPNType"="Key";"KeyDuration"="$SPNage";"ExpirationDate"="$EndDate";"URL"="$SPNurl";"AppID"="$GUID"}
        
        $SecretValue = ConvertTo-SecureString $Password -AsPlainText –Force
        $Secret = Set-AzureKeyVaultSecret -VaultName $KeyVaultName -Name $SPNname -SecretValue $SecretValue -Tags $Tags
    }
}
@markcowl markcowl added the Resource Authorization AzRole* in Az.Resources label Nov 22, 2016
@markcowl
Copy link
Member

@shuagarw please take a look

@donlockhart
Copy link
donlockhart commented Aug 2, 2017

I am also trying to have a SPN create other SPN's. Is this scenario supported? I get the same error mentioned above: "Resource not found for the segment 'me'"

@Make-Make
Copy link

Same error if i run it form Visual Studio Team Services build/release pipeline.

Resource not found for the segment 'me'.

basically, registered AD app (VSTS) tries to create AD app.
Is there workaround ?

@forrestcoward
Copy link

+1. I am trying to automate the creation of a SP from another SP and hitting this issue during a VSTS RM. Any workarounds? Thanks!

@sebbrochet
Copy link

@forrestcoward , @Make-Make , @donlockhart , @Hoppy7
There's an option we're using on our project to "automate everything".
It's based on a few assumptions

  • VSTS SPN should be able to do as much as we can do as Owner of the subscription and Global Administrator of the default AD tenant associated with it.
  • We've more trust in VSTS to do the right thing consistently than us when doing it multiple times at any time

Based on that, you just need to grant Company Administrator role to it and voila it'll be able to create other SPN and corresponding Principal.

You can use below code to do it using Powershell:

function configure-AAD-Role-VSTS
{
  try {
    # Previous VSTS naming convention
    $spnNameKeyword = 'VisualStudio*'
      [array]$roleAssignList = Get-AzureRmRoleAssignment | Select-Object DisplayName, ObjectId, RoleDefinitionName, ObjectType | Where-Object DisplayName -Like $spnNameKeyword

	# New VSTS naming convention based on Team/Project
    if(!$roleAssignList) {
      $spnNameKeyword = '<TEAM>-<Project>*'
      [array]$roleAssignList = Get-AzureRmRoleAssignment | Select-Object DisplayName, ObjectId, RoleDefinitionName, ObjectType | Where-Object DisplayName -Like $spnNameKeyword
    }

    if(!$roleAssignList) {
      Write-Host "ERROR: VSTS created SPN not found, can't give it Company Administrator role!" -BackgroundColor Red
    }

      foreach($roleAssign in $roleAssignList)
      {
          if ($roleAssign.RoleDefinitionName -eq "Contributor" -and $roleAssign.ObjectType -eq "ServicePrincipal")
          {        
        $spnName = $roleAssign.DisplayName                                            
        $adApp = Get-AzureRmAdApplication -DisplayNameStartWith $spnName
        $appId = $adApp.ApplicationId  
                        
        $role = Get-AzureADDirectoryRole | Where-Object { $_.DisplayName -eq "Company Administrator" }        
        $adSpn = Get-AzureADServicePrincipal -SearchString $spnName
        $member = Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId | Where-Object ObjectId -eq "$($adSpn.ObjectId)"

        if(!($member)) {
          Write-host "Giving 'Company Administrator' role to SPN $spnName..."
          Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $roleAssign.ObjectId
        }
        else {
          Write-host "SPN $spnName is already Company Administrator" 
        }
          }
      }
  }
  catch [System.Exception] {    
    $ErrorMessage = $_.Exception.Message    
    Write-host "Exception ($ErrorMessage)" 
    throw "ERROR: configure-AAD-Role-VSTS failed."
  }
}

@madsd
Copy link
Contributor
madsd commented Sep 20, 2018

The environments and customers I work with do not have the same amount of trust as @sebbrochet. Did anyone manage to figure out the least privilege approach to creating App Reg and Svc Principal through a VSTS Pipeline?

@bsiegel bsiegel added the Service Attention This issue is responsible by Azure service team. label Sep 26, 2018
@RobertoBorges
Copy link
RobertoBorges commented Nov 13, 2018

My environments do not have the same amount of trust as @sebbrochet. Did anyone manage to figure out the least privilege approach to creating App Reg and Svc Principal through a VSTS Pipeline?

@dexterlakin
Copy link

Hi all,

The Service Principal requires Owner permission to the subscription and the following API access:
Windows Azure Active Directory: "Manage apps that this app creates or owns"
Microsoft Graph: "Read and write directory data", "Access directory as the signed in user"

@danponting
Copy link

I have given the app registration that VSTS uses all of the permission that you have mentioned @teejam2, but I am still facing the same error message:

#[error]Resource not found for the segment 'me'.

Any ideas?

@dexterlakin
Copy link

@BurgerVanDan has an account administrator confirmed the permissions? Is the service principal an owner of the target subscription?

@danponting
Copy link

@teejam2 I have just realised that I dont not have permissions to 'grant' the app service the relevant permission as it is a customer subscription/AAD.

I will see if I can persuade on the global administrators to grant them for me. I will check back in when I have an update!

@SamirFarhat
Copy link

@teejam2 Thanks you, it worked !!

@SamirFarhat
Copy link

Just a note, you don't need Owner permissions, you need only User Access Administrator role over Azure if you want to use your SPN to assign permissions

@n0thingness
Copy link

Thank you @teejam2

I did some additional testing and as far as I can tell, the Application.ReadWrite.OwnedBy permission is the only one required by an SP in order to create another SP. In other words, you do not need to grant the other two Microsoft Graph permissions.

While testing which permissions were required, I found it helpful to execute the following powershell command after adding/removing a permission and granting admin consent: Clear-AzContext. Without this command, it appeared that the API permissions were being cached in the session.

@selflo
Copy link
selflo commented Sep 25, 2019

I still have this issue even when I added all API permission mentioned by @teejam2. I also made the SP as the subscription owner, tried Clear-AzContext, but no difference. The cmdlet used to create new SP with existing SP is

CommandType Name Version Source


Cmdlet New-AzADServicePrincipal 1.6.1 Az.Resources

What else I can do to debug or workaround this issue?

@selflo
Copy link
selflo commented Sep 25, 2019

I was testing with my own az subscription and directory and granted the admin consent with my user login(Admin). The same error details came back as original post when I ran cmdlet with -Debug

image

@ghost
Copy link
ghost commented Mar 16, 2020

I managed to create App Registration and Service Principal using the Azure Active Directory Graph (Legacy API) With Application.ReadWrite.OwnedBy.

image

image

$clientid = "123456"
$password = "****"
$appName = "my-permissiontest"
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($clientid, $secpasswd)
$application = New-AzADApplication -DisplayName $appName -IdentifierUris $appName
$sp = New-AzAdServicePrincipal -ApplicationObject $application
Remove-AzAdApplication -ApplicationId $application.applicationid

I tested all other suggestions here, but where only able to create App Registration, but not Service Principal.

@rharris-hs
Copy link

I want to confirm that adding Application.ReadWrite.OwnedBy from the LEGACY Azure Active Directory Graph API does seem to be the one permission required that allows this to work.

However, granting the same permission (Application.ReadWrite.OwnedBy) through the new Microsoft Graph API DOES NOT WORK.

There is now a deprecation warning message: "This application is using Azure AD Graph API, which is on a deprecation path. Starting June 30th, 2020 we will no longer add any new features to Azure AD Graph API. We strongly recommend that you upgrade your application to use Microsoft Graph API instead of Azure AD Graph API to access Azure Active Directory resources."

Can anyone explain what the difference is between the permissions for "Application.ReadWrite.OwnedBy" when using the Legacy API vs the new one? It would also be great to know what appropriate permissions that should be granted via the new API instead.

@Kinjara
Copy link
Kinjara commented Oct 21, 2020

Greetings,

As rharris-hs says - I was also able to conform the difference as well.
However we decided to accept a legacy in the assumption it would be fixed before being deprecated.. Now that it is deprecated it would be nice to have a way to do it...?

As for the current answer in this thread; "Access directory as the signed in user" would mean it can revert to the user identity used to call the AzDevOps pipeline (which in our case has no privileges but shouldn't be part of the solution). Secondly its one that is automatically flagged for us as undesired.

with kind regards,
Sebastian

@hdpoe
Copy link
hdpoe commented Feb 2, 2021

Hi, I don't know what that status of this is but this is still an outstanding problem for our org currently that we can't create a SP in Azure with another SP unless we grant it the Application.ReadWrite.OwnedBy in the Auzre AD Graph API. Is there a reason for this? Is there any updates on it? Also should a note be created about this on the documentation page for the New-AzADServicePrincipal command?

@t-muko
Copy link
t-muko commented Jun 29, 2021

Legacy Active Directory Grap API is still required to create and manage a service principal with another SP:

MicrosoftTeams-image

Service principal create API permission (microsoft.directory/servicePrincipals/create) can be granted via App roles:

MicrosoftTeams-image (1)

@mail-lwang
Copy link
mail-lwang commented Sep 26, 2021

Any update on this issue? Now that the "Azure Active Directory Graph" IS DEPRICATED, I cannot use it any more! Need to run Pipeline with Service Principle and create other SPs.

@mileee6
Copy link
mileee6 commented Nov 11, 2021

@mail-lwang have you found the solution? Since Azure Active Directory Graph is deprecated my automation is also not working... Im receiving error Resource not found for the segment 'me'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
customer-reported Resource Authorization AzRole* in Az.Resources Service Attention This issue is responsible by Azure service team.
Projects
None yet
Development

No branches or pull requests