Azure setting recursive ACL results in 403 - updating goes okay though - azure

I'm using the Az.Storage cmdlets in Powershell to set the permissions on an Azure Data Lake gen 2 storage account. I have "owner" permissions, along with "Data Storage Owner" via my Azure AD account.
I can run the cmdlet "Update-AzDataLakeGen2AclRecursive" without issue, but if i instead try to 'replace' the permissions, using "set-AzDataLakeGen2AclRecursive", i get the following error:
Set-AzDataLakeGen2AclRecursive : An error occurred while recursively changing the access control list. See the InnerException of type Azure.RequestFailedException with Status=403
and ErrorCode=SetAclMissingAces for more information. You can resume changing the access control list using ContinuationToken= after addressing the error.
At file.ps1:62 char:9
+ Set-AzDataLakeGen2AclRecursive -Context $context -FileSystem ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzDataLakeGen2AclRecursive], DataLakeAclChangeFailedException
+ FullyQualifiedErrorId : DataLakeAclChangeFailedException,Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.SetAzDataLakeGen2AclRecursiveCommand
I'm not entirely sure why i'd get a 403 in this scenario, as it appears i have the correct permissions on the account already. (Having created the storage account with that same account - and reading the documentation, and finding that 'Data Storage Owner' was required)
Any ideas here?

To answer this one - you must make sure your AD Principal has permissions at the container level to be able to access it in the first place.
For me - this meant granting my AAD Account read/write/execute + default perms on the container that i was attempting to modify before using the "Set-" cmdlet.

Related

How to reset credentials of an Azure service principal using an automation account PowerShell runbook?

I'm trying to reset the password credentials of a service principal (let's call it SP1) through the following PowerShell commands:
Remove-AzADSpCredential -ObjectId <SP1_objectId> -Force
$Password = New-AzADSpCredential -ObjectId <SP1_objectId>
This works well when I run it through the PowerShell by my own user account, which has an Owner role assigned to SP1.
I also have this code in a runbook in an automation account with a "run as account" service principal (let's call it SP2).
I assigned the ownership of SP1 to SP2 as well through the command Add-AzureADServicePrincipalOwner and confirmed it through Get-AzureADServicePrincipalOwner.
I expected the runbook to be able to run the Remove-AzADSpCredential command on the SP1 after making its service principal the owner of SP1. But I get the following error:
Remove-AzADSpCredential : Insufficient privileges to complete the operation. At line:43 char:9 + Remove-AzADSpCredential -ObjectId $key.Name -Force + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Remove-AzADSpCredential], Exception + FullyQualifiedErrorId : Microsoft.Azure.Commands.ActiveDirectory.RemoveAzureADSpCredentialCommand
And the same error for New-AzADSpCredential command as well.
I thought maybe the ownership of SP1 should be assigned to the App for the run as account, instead of its service principal.
So I also ran the following:
Add-AzureADServicePrincipalOwner -ObjectId <SP1_ObjectId> -RefObjectId <runasaccount_app_ObjectId>
But this wasn't possible, as I got the error:
Code: Request_BadRequest
Message: The reference target 'Application_xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx' of type 'Application' is invalid for the 'owners' reference.
So I assume the ownership should have been assigned only to SP2, and not to the app.
I looked at here but the accepted answer says
If your user accounts are the Owner of the service principal(Enterprise application), the command New-AzADSpCredential will work.
which is true in my case, and yet, it's not working when running the runbook.
I also looked at here and it seems I need to do the #1 which the OP describes as easy to do.
Any input on how to do this will be greatly appreciated.
If you want to use a service principal to add/remove credentials for another service principal, it is different from using a user account to do that.
I assigned the ownership of SP1 to SP2 as well through the command Add-AzureADServicePrincipalOwner and confirmed it through Get-AzureADServicePrincipalOwner.
This way is correct, but not only the Owner, also you need to give an Application.ReadWrite.OwnedBy Application permission in Azure Active Directory Graph (Not Microsoft Graph)API after that.
Navigate to the API permissions of your automation account corresponded AD App in the portal -> add the permission like below, don't forget to click the Grant admin consent for xxx button at last.
Then test it in the runbook, it works fine.
New-AzADSpCredential -ObjectId xxxxxxxxxxxxx
The combination of Owner and Application.ReadWrite.OwnedBy is the minimum privilege in this case, there are also other ways, you can also give the Application Administrator directory role as you saw here or Application.ReadWrite.All Application permission in Azure Active Directory Graph, both will work.

Insufficient privileges to complete the operation while invoking Get-AzADGroupMember

I have an Azure function in Powershell(v 2.0) with Az Module Installed and an assigned managed identity to manage resources within a bunch of subscriptions for a tenant say 'A'. Because of which I have been able to perform operations to handle VM/subscriptions management with commands like Get-AzVm, Set-AzContext etc.
In the function, there is a logic to check if a user is present within an Usergroup say 'readonlygroup' in AzureAD for tenant 'A'. And I'm trying to get the usergroup from the function by calling
$users = Get-AzADGroupMember -GroupDisplayName 'readonlygroup'
But I get an exception thrown
ERROR: Get-AzADGroupMember : Insufficient privileges to complete the operation.
At D:\home\site\wwwroot\{functionname}\run.ps1:110 char:18
+ ... $users = Get-AzADGroupMember -GroupDisplayName 'readonlygroup'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-AzADGroupMember], Exception
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ActiveDirectory.GetAzureADGroupMemberCommand
Script stack trace:
at <ScriptBlock>, D:\home\site\wwwroot\{functionname}\run.ps1: line 110
System.Exception: Insufficient privileges to complete the operation.
I'm assuming its because the identity associated with the Function app doesn't have appropriate access to Azure Active directory. I was able to assign role assignments to the app identity to manage subscriptions but I don't see any options on how to setup a similar configuration to access AD from function app.
How can I run this command from my azure powershell function?
Try going to your azure ad, roles and administrators, choose a role that allows you to perform the ps functions you want, in this case you are trying to read groups, so maybe directory readers then click add assignments. find your function name, or from the function app identity blade, copy the object id shown, then paste it in the add assignments searchbox, it should find it, add it there.. may take up to 24 hrs to take effect but usually much quicker, then you should be able to run those ps commands.
the azure role assignments you added from the identity blade in the function only gives it for example subscription access, not access to azure ad.

PnP Powershell Add-PnPOffice365GroupToSite Authorization_RequestDenied Azure Runbook

We are using an Azure Runbook with PnP PowerShell to automate provisioning of SharePoint Online and O365 groups.
To connect and authenticate through PnP PowerShell, we are using an AppId and AppSecret that have assigned to an Azure Run As account.
Connecting to PnP Powershell through the Connect-PnPOnline command passing in the AppId and AppSecret works nicely.
We are then able to create a new site using New-PnPTenantSite, however when we go to create a group using Add-PnPOffice365GroupToSite we get the following error.
{"odata.error":{"code":"Authorization_RequestDenied","message":{"lang":"en","value":"Insufficient privileges to
complete the operation."},"requestId":"fd2a5b37-98ea-40ab-bf39-5db8fafe9057","date":"2020-02-05T13:04:08"}}
At line:75 char:1
+ Add-PnPOffice365GroupToSite -Url "$siteFullUrl" -Alias "$MailboxName" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Add-PnPOffice365GroupToSite], ServerException
+ FullyQualifiedErrorId : EXCEPTION,SharePointPnP.PowerShell.Commands.Admin.AddOffice365GroupToSite
We have granted SharePoint tenant management privileges through the /_layouts/AppInv.aspx page, and also provided API access directly to the AppRegistration in Azure. We have assigned most permissions that relate to Groups, Sites and AD, however continue to receive the error above.
Does anyone have any info on what API permissions we need to assign to this app registration to allow it to create the office 365 group using this method?
The above screenshot shows the API permissions assigned to the app registration.
It turns out that certain operations require user interaction for auditing purposes - group creation being one of them.
Reference here with an answer from Andrew Connell -> https://github.com/SharePoint/sp-dev-docs/issues/3799

How to create SAS token to list\delete blobs

I tried creating SAS like this (ADDING "Read" permission changes nothing):
But it didnt work for me. I only want my script to get blob list, read metadata and delete old blobs.
Get-AzureStorageContainer : The remote server returned an error: (403)
Forbidden. HTTP Status Code: 403 - HTTP Error Message: This request is
not authorized to perform this operation.
Also, I'd like to know whats the minimum possible permissions to achieve my goal.
$ctx = New-AzureStorageContext -StorageAccountName xxx -SasToken zzz
$Containers = Get-AzureStorageContainer -Context $ctx
sample sas token:
?sv=2017-07-29&ss=b&srt=co&sp=dl&se=2018-03-31T21:24:06Z&st=2018-03-31T09:24:06Z&spr=https&sig=bWsg5sSPZF%2FaBXxfW6RoCH%2BlcFKBT6MFyMKTRM3I2jI%3D
So there are two things here:
You're getting 403 error: Assuming you're using the same SAS token as you have mentioned in the question along with Get-AzureStorageContainer Cmdlet, you will get this error. The reason for this is the purpose of this Cmdlet is to list blob containers in a storage account and for that you need to have Service permission in your SAS token (srt value in your SAS token should be sco instead of co). Because the required permission is not there in your SAS token, you are getting this 403 error. However if you use the same token along with Get-AzureStorageBlob, you should not get any error.
Necessary permissions for get blob list, read metadata and delete old blobs: For this, you would need the following permissions:
Allowed Services: Blobs (b)
Allowed resource types: Container (c) and Object (o)
Allowed permissions: List (l), Read (r) and Delete (d)
With this combination you should be able to list blobs from a blob container using Get-AzureStorageBlob, read its metadata and delete the blobs.
UPDATE
So what I did was I followed your steps and tried to list the blob containers using Get-AzureStorageContainer Cmdlet. I also got the same error :).
Then I ran the Cmdlet with Debug and Verbose switches and found that for each blob container, this Cmdlet tries to get the ACL.
_https://account.blob.core.windows.net/my-container?sv=2017-07-29&ss=b&srt=sco&sp=dl&se=2018-03-31T23:28:27Z&st=2018-03-31T15:2
8:27Z&spr=https&sig=signature&api-version=2017-04-17&restype=container&comp=acl.
Confirm The remote server returned an error: (403) Forbidden. HTTP
Status Code: 403 - HTTP Error Message: This request is not authorized
to perform this operation. [Y] Yes [A] Yes to All [H] Halt Command
[S] Suspend [?] Help (default is "Y"): y Get-AzureStorageContainer :
The remote server returned an error: (403) Forbidden. HTTP Status
Code: 403 - HTTP Error Message: This request is not authorized to
perform this operation. At line:1 char:1
+ Get-AzureStorageContainer -Context $ctx -Debug -Verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzureStorageContainer], StorageException
+ FullyQualifiedErrorId : StorageException,Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.GetAzureStorageCont
ainerCommand
Now the problem is that you can't fetch ACL for a container using a shared access signature, you would need to use the account key (same thing goes for creating a shared access signature). This is the reason you're getting 403 error back from the service.
Not sure you would classify this as a bug in Get-AzureStorageContainer or would want to put in a feature request allowing you to list blob containers without getting its ACL but they way things are today, you can't list blob containers using this Cmdlet and a SAS token.

Adding a new Azure AD App Credential - What specific permissions or role memberships are needed?

I am trying to add a new password credential for my Azure AD Application, through the Powershell commandlet and I run into an insufficient permissions error.
New-AzureRmADAppCredential -ApplicationId "<my app guid>" -Password "<a new password>" -EndDate (Get-Date).Addyears(2)
Error Details
New-AzureRmADAppCredential : Insufficient privileges to complete the operation.
At line:1 char:1
+ New-AzureRmADAppCredential -ApplicationId "<some guid> ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-AzureRmADAppCredential], Exception
+ FullyQualifiedErrorId : Authorization_RequestDenied,Microsoft.Azure.Commands.ActiveDirectory.NewAzureADAppCredentialCommand
I have the same behavior when I try to add a new secret through the UI as well.
What are the specific permissions I am missing?
Please note this Azure AD is synced with an on-prem AD. I suspect the on-prem AD permissions are also coming into play here.
Any advice?
In order to update an application you must be a Tenant Administrator or marked explicitly as an owner of the application.
You can most easily check these things using the Graph Explorer.
You can check if you are a tenant administrator of the tenant using this Graph Query:
https://graph.windows.net/myorganization/me/memberOf
And then looking for the tenant administrator directory role to be listed.
And you can check if you are an owner of the application with this query:
https://graph.windows.net/myorganization/applications/{Object ID}/owners

Resources