I am trying to create an Azure AD Group via the Graph API using a service principal. The intent is that the service principal will create the group in a Pipelines run.
The call I am using to attempt to create the group is
az rest --method post \
--uri 'https://graph.microsoft.com/v1.0/groups' \
--body '{"description": "A description", "displayName": "MyAppGroup", "mailEnabled": false, "mailNickname": "test", "securityEnabled": true, "owners#odata.bind": ["https://graph.microsoft.com/v1.0/users/oooooooo-oooo-oooo-oooo-oooooooooooo"]}' \
--headers "Content-Type=application/json"
To graph permissions, I have bound the API permission Group.Create to my service principal. To understand the permissions I am required to grant, I am following this page:
https://learn.microsoft.com/en-us/graph/api/group-post-groups?view=graph-rest-1.0&tabs=http#permissions
With the Group.Create permissions, when I run the rest call to the Graph API above, I get the following permission error
Forbidden({
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"date": "2020-11-02T13:31:35",
"request-id": "...",
"client-request-id": "..."
}
}
})
I completely understand that if I were to add the Directory.ReadWrite.All, I could make the group and would have all required permissions. However this permission is overscoped and would allow my service principal to disable users in the Active Directory tenant - something my organisation will now allow. Therefore I cannot grant my service principal this permission.
The documentation I have linked above implies to me that Group.Create is a sufficient permission to enable a service principal to create a group.
My question is what I am doing wrong, or what permissions am I missing to be able to create a group? Directory.ReadWrite.All is clearly overscoped to simply create an AD security group and so using it is not an option for me.
Hopefully this helps someone else - I realised the answer immediately after posting this.
I had added the property
"owners#odata.bind": ["https://graph.microsoft.com/v1.0/users/oooooooo-oooo-oooo-oooo-oooooooooooo"]
to the json post data.
Removing this property allowed me to create the group with just the Group.Create permission.
Adding the permission User.Read.All allows the service principal to read the user data for the owner, and so is sufficient to create the group with any necessary owners.
After adding this API permission, my service principal was able to create the group (with owners) as expected.
Related
I want to assign role Things.Reead.All, created in my app registration to a managed identity.
The app registration SP object id is 8055e1eb-0000-0000-9b77-00000000000
The Role definition looks like this
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"description": "Allow the application to read all things as itself.",
"displayName": "Read all things",
"id": "86a914fa-a862-4962-9975-000000000000",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Things.Read.All"
}
The only thing known about a system assigned managed identity is its object id, say
aad300-0872-0000-811d-00000000000
and I want to allow it to call the application 8055e1eb-0000-0000-9b77-00000000000 that expects to see the Role in access token.
I know I have to use the following api to do this.
https://graph.microsoft.com/v1.0/servicePrincipals/8055e1eb-0000-0000-9b77-00000000000/appRoleAssignedTo
{
"principalId": "aad300-0872-0000-811d-00000000000",
"resourceId": "8055e1eb-0000-0000-9b77-00000000000",
"appRoleId": "86a914fa-a862-4962-9975-000000000000"
}
I have wide but controlled access in my tenant. When I acquire a token from
az account get-access-token --resource https://graph.microsoft.com
and call the above, I get
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
What I need to figure out is the exact privilege that is needed to make this call.
As you did not answer my comment, I can just give you my own solution which used the service principal to login the azure cli, it works for me.
Please follow the steps below.
1.Create a new App Registration in azure ad, then get values for signing in and create a new application secret.
2.Navigate to the API permissions of the App, add the Application permission(not Delegated permission) Directory.ReadWrite.All of Microsoft Graph, don't forget to click the Grant admin consent for xxx button at last.
Note: From the doc, the AppRoleAssignment.ReadWrite.All permission is enough, but per my test, it will not work, not sure if it is a bug, I have decoded the token, the token has the AppRoleAssignment.ReadWrite.All permission.
3.In azure cli, run the commands below to get the token.
az account clear
az login --service-principal --allow-no-subscriptions --username '<application-id>' --password '<application secret>' --tenant '<tenant-id>'
az account get-access-token --resource https://graph.microsoft.com
4.I test the token to call the api - Grant an appRoleAssignment for a service principal to grant the app role for the system-assigned identity of my funtion app,it works fine.
Check it in the portal:
I have an Azure Function with Azure Active Directory authentication enabled (including "Action to take when request is not authenticated" = "Log in with Azure Active Directory"). Additionally the option "User assignment required?" of the Azure Function related service principal (sp_func) is set to "Yes" to avoid everybody in the tenant being able to in the end run the function.
The goal is to have a single security group (that can include users as well as service principals) that is added to "Users and groups" of sp_func so that the assignment to the group decides if the function can be accessed or not. With users this works fine but not with service principals (sp_nonfunc). For them (sp_nonfunc) to work I have to set the permissions for them (sp_nonfunc) what in the end allows them to interact with the Azure Function no matter if they (sp_nonfunc) are assigned to the group or not.
Is it possible that I can just add a service principal (sp_nonfunc) to a group with the group being added to sp_func and then be able to execute the Function by using sp_nonfunc (without giving explicit permissions to sp_nonfunc)?
EDIT: it also does not seem to be possible to add sp_nonfunc to sp_func directly even if I defined an own appRole in the Manifest. The only way currently seems to be to add permissions on sp_nonfunc for sp_func - but that is what I want to avoid.
EDIT2: here how I have defined the role in the sp_func manifest
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"displayName": "AzureFunctionAccess",
"id": "xxx-xxx-xxx-xxx-xxx",
"isEnabled": true,
"description": "Access Azure Function.",
"value": "AzureFunctionAccess"
}
]
EDIT3: when I don't assign a role directly to sp_nonfunc but just add sp_nonfunc to the security group I get, when making a request to https://login.microsoftonline.com/<tenant id>/oauth2/token with resource = Application ID URI of the registered app of sp_func:
{
"error": "invalid_grant",
"error_description": "AADSTS501051: Application 'xxx-xxx-xx-xx-xx'(xxx) is not assigned to a role for the application 'https://xxx'(xxx).\r\nTrace ID: xxx-xxx-xx-xx-xx\r\nCorrelation ID: xxx-xxx-xx-xx-xx\r\nTimestamp: xx-xx-xx xx:xx:xxZ",
"error_codes": [
501051
],
"timestamp": "xx-xx-xx xx:xx:xxZ",
"trace_id": "5xxx-xxx-xx-xx-xx",
"correlation_id": "xxx-xxx-xx-xx-xx",
"error_uri": "https://login.microsoftonline.com/error?code=501051"
}
This way will not work, to use a service principal(in your case, the sp_nonfunc) get the token for the function app(sp_func), you need to give the API permission for the sp_nonfunc.
Navigate to the App Registration related to the sp_nonfunc in the portal -> API permissions -> add the AzureFunctionAccess you defined, at last click the Grant admin consent for xxx button.
Then get the token with the client credential flow, it will work fine. (I use the v2.0 endpoint, if you use the v1.0, it will also work.)
For more details about the steps, I wrote in this post before, you could refer to it.
Trying to add members to a group using Microsoft graph API, was able to add member to the group to which Application owner is the owner of but not to the group that was created by other member.
When I try to add member to the group and Application owner is not the owner of the group, I am receiving the following error
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "2c5a99ff-70XXXXXXXXXXXXXXXXX",
"date": "2X-XX-XXXX 23:42:54"
}
}
}
These are the permissions given to the App API
Can someone help me understand how the add member to group works with Azure? only group owner will be able to add member to the group? Is there any configuration that needs to be enabled for Application to let Application owner add member to any group?
If you are using Delegated permissions, the effective permissions of a token will be the combined permissions of the app and user.
If the user does not have the necessary role/ownership, then your app can't do it either.
If your app needs to act with more permissions than the user has, you'll need to use application permissions instead of delegated permissions.
To use app permissions, your app back-end must acquire tokens using the client credentials flow, which does not involve a user.
In this case only the application's app permissions matter, delegated permissions will have no effect.
I have a requirement to auto provision O365 groups in desired Geo location (i.e CAN, Default being EU), I'm using AAD app permissions to authenticate to Graph API. Need help in achieving this.
I'm aware that the teams created using delegated permission will be created in the regions specific to the delegated user and found the "preferredDataLocation" property of the graph group type is updated as that of the user.
I tried creating group with this property set to desired location code(i.e CAN) with application permission and I get the below error.
Request Body:
{
"description": "Muti-Geo Graph API",
"displayName": "Teams Multi-Geo Graph API",
"groupTypes": [
"Unified"
],
"mailEnabled": true,
"mailNickname": "TeamsMultiGeoGraphAPI",
"securityEnabled": false,
"owners#odata.bind": [
"https://graph.microsoft.com/v1.0/users/XXXXXX"
],
"preferredDataLocation":"CAN"
}
Response:
"code": "Authorization_RequestDenied",
"message": "The requesting user is not authorized to set group preferred data location."
Please let me know if there is any way I can create O365 groups in desired geo location.
Note: Multi-Geo is enabled and CAN region is available in the tenant.
I had the same issue. Adding the Directory.ReadWrite.All to the list of permissions of my Azure AD App solved the issue.
Here are the list of the required permissions to perform this API call:
Group.Create, Group.ReadWrite.All, Directory.ReadWrite.All
Documentation: Here.
I've seen posts like this one where there is confusion on exactly what permission is required to allow a ServicePrincipal to call Get-AzureRmRoleAssignment when logging in using Login-AzureRmAccount.
In my case if I call Get-AzureRmRoleAssignment with the -debug flag I can capture the following error in the body of the HTTP response:
Body:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
}
}
}
I have set perms for the application as follows... first the Azure AD access:
And then the Microsoft Graph access:
This still gives the authZ failure error. I have even tried an experiment where I gave the app ALL perms for each API, and that still did not work.
What's missing? What perms EXACTLY are needed to allow read only programmatic access to list the role assignments with this call?
First, as I answered in that case, Get-AzureRmRoleAssignmentdoesn't only needs read access for role assignment with Azure REST API permission but also needs Read directory data permission with Azure AD Graph API. After adding permissions,
Add AAD Graph API Permission:
You also need to click Grant permissions button to do admin consent.
Add Azure REST API Persmssions:
Also, before adding AAD graph API permissions for your sp, ensure your sp has permissions with Azure REST API by assigning a role (E.g. A Contributor Role) to it from Subscriptions RBAC(IAM).
I test this and succeeded.