Having trouble understanding Azure's Roles JSON - azure

Its just a concept im having trouble understanding with the wildcard * and what that means, so here we have two roles Owner and contributor.
"Name": "Contributor",
"Id": "b24988ac-6180-42a0-ab88-20f7382dd24c",
"IsCustom": false,
"Description": "Lets you manage everything except access to resources.",
"Actions": ["*"],
"NotActions": [
"Microsoft.Authorization/*/Delete",
"Microsoft.Authorization/*/Write",
"Microsoft.Authorization/elevateAccess/Action'],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [],
"/"
Name : Owner
Id : 8e3af657-a8ff-443c-a75c-2fe8c4bcb635
IsCustom : False
Description : Grants full access to manage all resources, including the ability to assign roles in Azure RBAC.
Actions : {*}
NotActions : {}
DataActions : {}
NotDataActions : {}
AssignableScopes : {/}
So my hang up is use of the astrisk, i know * under Owner means everything but with contributor, why is it used under the NotActions permissions? Why is it "Microsoft.Authorization/*/Delete" instead of Microsoft.Authorization/Delete". The permission in question stops the contributor from deleting users. So i know how these roles and permissions work, im just really struggling with the syntax. I have read the documentation on microsoft learn but there is something i clearly dont understand about the *. Does anyone with any knowledge know of a way of explaining this to help clear it up or maybe someone could point me to some better documentation? Any help would be greatly appreciated.

Why is it "Microsoft.Authorization/*/Delete" instead of
Microsoft.Authorization/Delete".
To understand this, please see this link especially Operations format section.
Essentially each operation is specified in {Company}.{ProviderName}/{resourceType}/{action} format.
So when you specify the operation as Microsoft.Authorization/*/Delete, you're essentially allowing delete operation on all the resources under Microsoft.Authorization resource provider.
This format also enables you to specify actions granularly at each resource level under a resource provider.

Related

How to assign Access Policies to an Azure Key Vault using Blueprints

I am creating a key vault through an Azure Blueprint: it gets created with no problem.
The thing is that, in order to access the Key Vault (Listing it, putting or getting values) Access Policies must be configured.
With ARM templates, I could insert a section like :
"accessPolicies": [
{
"tenantId": "22222222-3333-4444-aaaa-eeeeeeeeeeee",
"objectId": "77777777-6666-4444-8888-111111111111",
"permissions": {
"keys": [
"Get",
...
"Restore"
],
"secrets": [
"Get",
...
"Restore"
],
"certificates": []
}
},
but I'd need to have a TenantId and an ObjectId to hardcode, or to get as parameter, which is not the right way to do it.
Unfortunately I could not find a way to assign these access policies to the Key Vault, without which the key vault itself just can't be used, unless making those settings manual (and deleting them each time the blueprint is upgraded).
Is there a guideline or a best practice to do this in the proper way ?
The tenantId you can get dynamically using "[subscription().tenantId]". See official documentation.
Regarding the objectId, using a parameter is usually the right way as stated in this answer. ObjectIDs are not on the same layer as ARM components and therefore there aren't real way to get those dynamically using ARM.
Starting from the answer from #jul_DW, I realized that ARM could not set in an easy way users, so I should have used to something in the Blueprint.
And infact, one of the key features for Blueprint is Role Assignment.
To use this approach we need to enable the RBAC for the Key Vault, but that is done easily in the ARM template itself:
...
"type": "Microsoft.KeyVault/vaults",
"properties": {
...
"enableRbacAuthorization": true,
...
}
Once the RBAC is enabled, the ARM template should stay away from assigning permissions, and the Role Assignment feature from Blueprints should be used.
In my case, I assigned a Key Vault Administrator role to the needed user group, that can be indicated as a parameter. In this way the ARM template is kept as simple as possible, and at the same time we have a great flexibility in assigning roles to different users in the various environments.

Deny permissions to execute PowerShell Get-AzAutomationCertificate

I am trying to create a custom reader role on Azure that does not allow the user to run the PowerShell command Get-AzAutomationCertificate. I have gone through the options and removed quite a few permissions related to reading certificates from the automation service provider. However, it appears it is still not enough.
These are the deny options present in the custom role :
"notActions": [
"Microsoft.Automation/automationAccounts/listKeys/action",
"Microsoft.Automation/automationAccounts/certificates/read",
"Microsoft.Automation/automationAccounts/certificates/getCount/action",
"Microsoft.Automation/automationAccounts/jobs/read",
"Microsoft.Automation/automationAccounts/jobs/runbookContent/action",
"Microsoft.Automation/automationAccounts/credentials/read",
"Microsoft.Automation/automationAccounts/runbooks/content/read",
"Microsoft.Automation/automationAccounts/runbooks/read",
"Microsoft.Automation/automationAccounts/python2Packages/read",
"Microsoft.Automation/automationAccounts/python3Packages/read",
"Microsoft.Automation/automationAccounts/privateEndpointConnectionProxies/read",
"Microsoft.Automation/automationAccounts/connections/read",
"Microsoft.Automation/automationAccounts/connectionTypes/read
]
More details about the command :
https://github.com/Azure/azure-powershell/blob/master/src/Automation/Automation/help/Get-AzAutomationCertificate.md
Any ideas on how to achieve this?
Thank you
Firstly, I would like to clarify that the NotActions permission specifies the management operations that are excluded from the allowed Actions. See reference here.
So if the Action is not included in Actions, it's unnecessary to put it into NotActions in order to make it lose effectiveness. In this case, the user will not have the permission to do the action.
The action "Microsoft.Automation/automationAccounts/certificates/read" is what you want to make the PowerShell command Get-AzAutomationCertificate effective. Please note that it allows Get-AzAutomationCertificate to be executed but won't return results.
Here is my example:
{
"Name": "Custom Role 2",
"Id": null,
"IsCustom": true,
"Description": "Don't allow for Get-AzAutomationCertificate",
"Actions": [
"Microsoft.Automation/automationAccounts/certificates/read",
"Microsoft.Automation/automationAccounts/read"
],
"NotActions": [
"Microsoft.Automation/automationAccounts/certificates/read"
],
"AssignableScopes": [
"/subscriptions/{subscription id}"
]
}
Please pay attention to the note in above link:
If a user is assigned a role that excludes an operation in NotActions,
and is assigned a second role that grants access to the same
operation, the user is allowed to perform that operation. NotActions
is not a deny rule – it is simply a convenient way to create a set of
allowed operations when specific operations need to be excluded.
After you update the custom role and assign it to the user, you should reopen an PowerShell window and re-login with the user. Then it will work for you.

Azure course that tries to use Azure Cloud Shell fails with "RequestDisallowedByPolicy" using free account

I was asked by Azure Support to post this question, just to see if anyone had a useful opinion.
I am stepping through MS Azure training courses. I created the usual free account to go through these. I've gone through a few dozen of them, and am now at this one:
https://learn.microsoft.com/en-us/learn/modules/secure-and-isolate-with-nsg-and-service-endpoints/3-exercise-network-security-groups?source=learn
This attempts to use the Azure PowerShell service. I had some trouble getting to the PowerShell page. It appears that if I'm not already logged into the portal, it goes into a semi-infinite loop, trying to get to the shell page, then trying to login, then the shell page, and finally it gives up and says "We couldn't sign you in. Please try again.".
However, I was able to work around this. If in a separate tab, I log into the Azure Portal, and then go back and follow the link to Azure Cloud Shell, it passes the login gate and sends me to the page where I choose Bash or PowerShell. The course specifies using Bash. When I select that, it then asks me to create a Storage object. When I confirm that, it gives me the following error (subscription id elided):
{
"error": {
"code": "RequestDisallowedByPolicy",
"target": "cs733f82532facdx4f04x95b",
"message": "Resource 'cs733f82532facdx4f04x95b' was disallowed by policy. Policy identifiers: '[{\"policyAssignment\":{\"name\":\"Enforce tag on resource\",\"id\":\"/subscriptions/xxxxx/providers/Microsoft.Authorization/policyAssignments/740514d625684aad84ef8ca0\"},\"policyDefinition\":{\"name\":\"Enforce tag on resource\",\"id\":\"/subscriptions/xxxxx/providers/Microsoft.Authorization/policyDefinitions/be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e\"}}]'.",
"additionalInfo": [
{
"type": "PolicyViolation",
"info": {
"policyDefinitionDisplayName": "Enforce tag on resource",
"evaluationDetails": {
"evaluatedExpressions": [
{
"result": "True",
"expressionKind": "Field",
"expression": "tags[Department]",
"path": "tags[Department]",
"targetValue": "false",
"operator": "Exists"
}
]
},
"policyDefinitionId": "/subscriptions/xxxxx/providers/Microsoft.Authorization/policyDefinitions/be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e",
"policyDefinitionName": "be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e",
"policyDefinitionEffect": "deny",
"policyAssignmentId": "/subscriptions/xxxxx/providers/Microsoft.Authorization/policyAssignments/740514d625684aad84ef8ca0",
"policyAssignmentName": "740514d625684aad84ef8ca0",
"policyAssignmentDisplayName": "Enforce tag on resource",
"policyAssignmentScope": "/subscriptions/xxxxx",
"policyAssignmentParameters": {
"tagName": {
"value": "Department"
}
}
}
}
]
}
}
I think the simple conclusion from this is that my free account doesn't have enough rights to do what is needed here. The documentation I've read seems to imply that I have to get additional rights on the account in order to do this. However, I'm just using a free account that I created to go through the Azure training courses. It doesn't really make sense to ask me to do this. I've seen other Azure courses create a temporary sandbox supposedly because they have particular objects pre-created in the sandbox, but I'm also thinking that the sandbox has particular permissions that are not available in the free account. It seems to me that the only reasonable fix for this problem is for that course to be refactored to use a temporary sandbox with the correct permissions.
I'm just looking for any opinions on this, and confirmations that this is what should be done.
It doesn't look like you are creating resource, cloudshell storage, on your free subscription. Except if you added to a Work/Corporate tenant.
From the information you provide, subscription you are trying to use has a policy to enforce tags Department, mean any resource created should have a tag with Department information.

Azure custom role: authorize role assignment for a specific set of roles

I am trying to create a custom role in Azure that would allow Subscriptions "owners" to do quite everything but cancelling/renaming their own subscriptions or moving into another management group.
I would also like them to be able to grant right access to who they want (especially built-in "Contributor" role) but without allowing them to grant "Owner" right, otherwise my custom role could be tricked easily.
I ended up with the following custom role definition which is so far nice and working, apart from the role assignment of course:
{
"Name": "MyCustomRole",
"IsCustom": true,
"Description": "Role designed for Azure subscriptions ownership limitations",
"Actions": [
"*"
],
"NotActions": [
"Microsoft.Management/managementGroups/subscriptions/write",
"Microsoft.Subscription/cancel/action",
"Microsoft.Subscription/rename/action"
],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/providers/Microsoft.Management/managementGroups/root.mg"
]
}
In the Azure documentation, the only operation I found for role assignment is Microsoft.Authorization/roleAssignments/write.
Is there any way to restrict that - to Contributor role assignment for instance - directly in the custom role?
Azure Policy might technically do the trick (not even sure), but since some operational/experts/whatever guys might end up as Owner, I do not want the policy engine to display "non-compliant" resources. It would lead customers to misunderstandings that I would like to avoid.
You might want to try Azure Policy, which you can apply on top of your IAM model. You can assign a policy on the Subscription or Management Group level, based on your governance structure.
Policy definition below will block EVERY request trying to assign "Owner" role with no exception. Built-in Owner role is represented by "8e3af657-a8ff-443c-a75c-2fe8c4bcb635", same GUID across all Azure tenants.
However Role assignments of other RBAC roles would still be possible. This should fullfill your use case.
https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
{
"policyType": "Custom",
"mode": "All",
"displayName": "DenyOwnerAssisgnment",
"policyRule": {
"if": {
"allOf": [
{
"field": "Microsoft.Authorization/roleAssignments/roleDefinitionId",
"contains": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
},
{
"field": "type",
"equals": "Microsoft.Authorization/roleAssignments"
}
]
},
"then": {
"effect": "deny"
}
},
"type": "Microsoft.Authorization/policyDefinitions"
}
To my knowledge - no, you cannot be granular. you can only restrict a specific action.
ps. technically this is correct. but the policy usage above is really clever ;)
Yes it should be possible when you assign a policy, so it's not part of the definition but assignment. You can assign policy on the subscription-level scope, and exclude resource groups. You can do that via "notScopes".
Please see Azure Policy docs for how to do this (chapter Excluded scopes)
The scope of the assignment includes all child resource containers and
child resources. If a child resource container or child resource
shouldn't have the definition applied, each can be excluded from
evaluation by setting notScopes. This property is an array to enable
excluding one or more resource containers or resources from
evaluation. notScopes can be added or updated after creation of the
initial assignment.
https://learn.microsoft.com/en-us/azure/governance/policy/concepts/assignment-structure
You can include excluded scopes in the portal when assigning Policy or through PowerShell by including -NotScope parameter.

How can I get the guids of Graph API permissions programmatically for an Azure AD application?

I am trying to add required permissions to an Azure AD application. I already know how to replicate information from a downloaded manifest through a PATCH REST call, e.g.
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "7b9103a5-4610-446b-9670-80643382c1fa",
"type": "Scope"
},
{
"id": "5df07973-7d5d-46ed-9847-1271055cbd51",
"type": "Scope"
}
]
}
]
As explained by Christer Ljung on his blog http://www.redbaronofazure.com/?page_id=181.
But the mystery remains how I can "convert" human-readable scopes such as Mail.Read to these obscure guids. I have read the following blog of Sahil Malik's at http://blah.winsmarts.com/2015-1-Programmatically_register_native_apps_in_Azure_AD_or_Office_365.aspx that explains how to get a list of available guids for a particular ServicePrincipal. E.g. through an http get to https://graph.windows.net/<tenant-id>/servicePrincipals()?api-version=1.6&$filter=appId%20eq%20'00000002-0000-0ff1-ce00-000000000000'> (Exchange) but when I try to get the list of available scopes of ServicePrincipal 00000003-0000-0000-c000-000000000000 (I believe the one for Graph API) the return value is just empty.
Interestingly, with Fiddler I was able to capture an http post request which contains all the guids when adding the permissions through Azure Portal.
Anyone any clue how I can do this programmatically?
After investigation, I discover a way to get permission guid using azure-cli. Share here in case anyone is finding this:
get all permisson and their GUID of a certain service principal by display-name, app-id or object-id. (Note that display-name is not unique and can maps multiple service principal)
$ az ad sp list --filter "displayName eq 'Microsoft Graph'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
$ az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table | head
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
Run the below command to get full information of certain service principal including its oauth2Permissions and servicePrincipalNames, etc.
az ad sp show --id 00000003-0000-0000-c000-000000000000 >microsoft_graph_permission_list.json
# microsoft_graph_permission_list.json
{
...
"appDisplayName": "Microsoft Graph",
"appId": "00000003-0000-0000-c000-000000000000",
"objectId": "b19d498e-6687-4156-869a-2e8a95a9d659",
"servicePrincipalNames": [
"https://dod-graph.microsoft.us",
"https://graph.microsoft.com/",
"https://graph.microsoft.us",
"00000003-0000-0000-c000-000000000000/ags.windows.net",
"00000003-0000-0000-c000-000000000000",
"https://canary.graph.microsoft.com",
"https://graph.microsoft.com",
"https://ags.windows.net"
],
"appRoles": [...],
"oauth2Permissions": [
{
"adminConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read and write all users' full profiles",
"id": "204e0828-b5ca-4ad8-b9f3-f32a958e7cc4",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read and write all users' full profiles",
"value": "User.ReadWrite.All"
},
{
"adminConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read all users' full profiles",
"id": "a154be20-db9c-4678-8ab7-66f6cc099a59",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read all users' full profiles",
"value": "User.Read.All"
},
...
]
...
}
Few things to say about this topic.
First, it is important to note that all of the OAuth2Permission Scopes are registered on the main Application Object in the developer's tenant. Thus, in general, you would not have access to that information, since it would be in a tenant where you are not a user. So as an external developer, these permission scopes are not discoverable via our APIs.
Second, you are able to see that the Azure Portal has access to this information because it has elevated access to query the OAuth2Permissions for all resources in all tenants. This is how our UX is able to populate all the permissions for all the various external and internal resources that you want to use in your tenant. The portal will first check which service principals are in your tenant (service principals get provisioned most commonly once you consent to use the application), then it will look up the Application Object that corresponds to that service principal, and find all the permission scopes. This behavior will hopefully allow you to only see the resource applications which are relevant to you, rather than populating your screen with all possible resources.
Finally, moving forward we are looking to take a step back from having to statically register permissions that clients require to call resource applications. Instead we will be pushing a new Incremental and Dynamic Consent framework. You will note that here that we are taking a dependency on the scope names, rather than the ObjectID GUIDs of those permissions as we did in the past. But still, I agree with you in general that the discoverability of the scopes that resources expose is very heavily dependent their own public documentation. I imagine in the future there might be an endpoint which exposes all the scopes available on a particular resource, but I know of no such work to do this in the near future.
Let me know if this helps!

Resources