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

User Assigned Managed Identity: Insufficient privileges to complete the operation #2552

Closed
jelleholtkamp opened this issue Jan 31, 2024 · 5 comments

Comments

@jelleholtkamp
Copy link

jelleholtkamp commented Jan 31, 2024

When using a user assigned managed identity in a function app, I get an insufficient privileges error on all commands. I have the appropriate permissions (such as user.read.all) set up on the Enterprise Application representing my user assigned managed identity.
The connection is succesful, as I see the welcome message.

To Reproduce

  • Create a powershell function app
  • Create a function with the following run.ps1:
Input bindings are passed in via param block.
param($Timer)

# Get the current universal time in the default string format.
$currentUTCtime = (Get-Date).ToUniversalTime()
$threshold = 30

# The 'IsPastDue' property is 'true' when the current function invocation is later than scheduled.
if ($Timer.IsPastDue) {
    Write-Host "PowerShell timer is running late!"
}
Connect-MgGraph -Identity -ClientId "[user assigned managed identity client id]"

Get-MgContext

Get-MgUser -UserId "[valid user id]"

Expected behavior
Output the desig

Debug Output

2024-01-31T13:25:37Z   [Error]   ERROR: [Authorization_RequestDenied] : Insufficient privileges to complete the operation.

Exception             : 
    Type    : System.Exception
    Message : [Authorization_RequestDenied] : Insufficient privileges to complete the operation.
    HResult : -2146233088
TargetObject          : { UserId = [redacted], Property = , ExpandProperty =  }
CategoryInfo          : InvalidOperation: ({ UserId = [redacted]…ExpandProperty =  }:<>f__AnonymousType12`3) [Get-MgUser_Get], Exception
FullyQualifiedErrorId : Authorization_RequestDenied,Microsoft.Graph.PowerShell.Cmdlets.GetMgUser_Get
ErrorDetails          : Insufficient privileges to complete the operation.
                        
                        Status: 403 (Forbidden)
                        ErrorCode: Authorization_RequestDenied
                        Date: 2024-01-31T13:25:36
                        
                        Headers:
                        Cache-Control                 : no-cache
                        Transfer-Encoding             : chunked
                        Vary                          : Accept-Encoding
                        Strict-Transport-Security     : max-age=31536000
                        request-id                    : 7c05a291-8feb-49c3-a3d9-9bca265ae69c
                        client-request-id             : 5a02e8ce-f6ce-48f4-8a88-69869c15439a
                        x-ms-ags-diagnostic           : {"ServerInfo":{"DataCenter":"West Europe","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"AM4PEPF0002BAAC"}}
                        x-ms-resource-unit            : 1
                        Date                          : Wed, 31 Jan 2024 13:25:36 GMT
                        
                        
InvocationInfo        : 
    MyCommand        : Get-MgUser_Get
    ScriptLineNumber : 16
    OffsetInLine     : 1
    HistoryId        : 1
    ScriptName       : C:\home\site\wwwroot\[redacted]\run.ps1
    Line             : Get-MgUser -UserId "[redacted]"
                       
    PositionMessage  : At C:\home\site\wwwroot\[redacted]\run.ps1:16 char:1
                       + Get-MgUser -UserId "[redacted]"
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    PSScriptRoot     : C:\home\site\wwwroot\[redacted]
    PSCommandPath    : C:\home\site\wwwroot\[redacted]\run.ps1
    InvocationName   : Get-MgUser
    CommandOrigin    : Internal
ScriptStackTrace      : at Get-MgUser<Process>, C:\home\data\ManagedDependencies\2401301408275440139.r\Microsoft.Graph.Users\2.12.0\exports\ProxyCmdletDefinitions.ps1: line 15849
                        at <ScriptBlock>, C:\home\site\wwwroot\[redacted]\run.ps1: line 16

Module Version
2.12.0

PSVersionTable
Name Value


PSVersion 7.2.13
PSEdition Core
GitCommitId 7.2.13
OS Microsoft Windows 10.0.14393
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0

Environment Data

@jelleholtkamp
Copy link
Author

jelleholtkamp commented Jan 31, 2024

Get-MgContext output:

2024-01-31T15:00:41Z [Information] OUTPUT: Scopes :
2024-01-31T15:00:41Z [Information] OUTPUT: AuthType : ManagedIdentity
2024-01-31T15:00:41Z [Information] OUTPUT: TokenCredentialType : ManagedIdentity
2024-01-31T15:00:41Z [Information] OUTPUT: CertificateThumbprint :
2024-01-31T15:00:41Z [Information] OUTPUT: CertificateSubjectName :
2024-01-31T15:00:41Z [Information] OUTPUT: Account :
2024-01-31T15:00:41Z [Information] OUTPUT: AppName : [redacted]
2024-01-31T15:00:41Z [Information] OUTPUT: ContextScope : Process
2024-01-31T15:00:41Z [Information] OUTPUT: Certificate :
2024-01-31T15:00:41Z [Information] OUTPUT: PSHostVersion : 7.2.13
2024-01-31T15:00:41Z [Information] OUTPUT: ManagedIdentityId : [redacted]
2024-01-31T15:00:41Z [Information] OUTPUT: ClientSecret :
2024-01-31T15:00:41Z [Information] OUTPUT: Environment : Global
2024-01-31T15:00:41Z [Information] OUTPUT:

The scopes part is empty. I cannot add the -Scopes parameter to the Connect-MGGraph cmdlet when using managed identity. I suspect that is part of the issue.

@SeniorConsulting
Copy link

Have you added the API permissions to the Managed Identity? You can check in the Entra ID portal under Enterprise Applications (specifically the Permissions blade)

image

If you haven't, then you'll need to use New-MgServicePrincipalAppRoleAssignment to assign permissions. If you haven't done that before, reply here - I've got a function which might be of use.

@salbeck-sit
Copy link

@SeniorConsulting I'm fiddling with SPN permissions in another context and would certainly like to see what that function could do for my project.

@jelleholtkamp
Copy link
Author

jelleholtkamp commented Feb 1, 2024

Have you added the API permissions to the Managed Identity? You can check in the Entra ID portal under Enterprise Applications (specifically the Permissions blade)

image

If you haven't, then you'll need to use New-MgServicePrincipalAppRoleAssignment to assign permissions. If you haven't done that before, reply here - I've got a function which might be of use.

Yes I did that. I added all the permissions that were output by the (Find-MgGraphCommand -Command get-mguser).permissions using the following script:

$graphPermissions = @(
    "DeviceManagementApps.Read.All",
    "DeviceManagementApps.ReadWrite.All",
    "DeviceManagementConfiguration.Read.All",
    "DeviceManagementConfiguration.ReadWrite.All",
    "DeviceManagementManagedDevices.Read.All",
    "DeviceManagementManagedDevices.ReadWrite.All",
    "DeviceManagementServiceConfig.Read.All",
    "DeviceManagementServiceConfig.ReadWrite.All",
    "Directory.Read.All",
    "Directory.ReadWrite.All",
    "User.Read",
    "User.Read.All",
    "User.ReadBasic.All",
    "User.ReadWrite",
    "User.ReadWrite.All",
    "DeviceManagementApps.Read.All",
    "DeviceManagementApps.ReadWrite.All",
    "DeviceManagementConfiguration.Read.All",
    "DeviceManagementConfiguration.ReadWrite.All",
    "DeviceManagementManagedDevices.Read.All",
    "DeviceManagementManagedDevices.ReadWrite.All",
    "DeviceManagementServiceConfig.Read.All",
    "DeviceManagementServiceConfig.ReadWrite.All",
    "Directory.Read.All",
    "Directory.ReadWrite.All",
    "User.Read.All",
    "User.ReadBasic.All",
    "User.ReadWrite.All"
)
$uamiDisplayname = '[redacted]'
$graphAppId = "00000003-0000-0000-c000-000000000000"
$graphServicePrincipal = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"

foreach($permission in $graphPermissions){
    $appRole = $GraphServicePrincipal.AppRole | Where-Object {$_.Value -eq $Permission -and $_.AllowedMemberType -contains "Application"}
    $managedIdentity = (Get-AzADServicePrincipal -Filter "displayName eq '$uamiDisplayname'")
    New-AzADServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentity.id `
        -ResourceId $GraphServicePrincipal.id -AppRoleId $AppRole.Id
}

The permissions are displayed on the permissions tab in the enterprise application.

As a means of troubleshooting, I also had the function app output a token using the Get-AzAccessToken and using that to connect using Connect-MgGraph -AccessToken $secureToken. Connection is succesful, but same error when trying to run any command I should be able to. When I inspect the token, it also has no scopes.

@jelleholtkamp
Copy link
Author

I just redeployed everything (my function app + associated resources and the user assigned managed identity) and now it's working. No idea what was wrong since I triple checked that the correct managed identity was associated and the permissions were set, and confirmed the managed identity ID by the Get-MgContext command but at least it's working again.

@salbeck-sit you can refer to my previous comment for the commands to set the permissions. Make sure to replace the values in the $graphPermissions array (and to not paste the permissions twice like I did). You should probably move the $managedIdentity = (Get-AzADServicePrincipal -Filter "displayName eq '$uamiDisplayname'") outside of the foreach loop as well, as it doesn't really make sense for it to be in the loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants