I'm trying to create an access review using the Microsoft Graph API. I can't figure out how to scope (target) multiple groups in the same access review using the available documentation and samples. This is easily done when creating one in the Azure portal.
My goal is to have one access review that scope two or three Azure AD groups. These groups are granting access to Reader, Contributor and Owner role within a subscription.
Here is a sample code that I used to create an access review that scope one group.
{
"displayName": "Testing",
"descriptionForAdmins": "Testing",
"descriptionForReviewers": "Testing",
"scope": {
"#odata.type": "#microsoft.graph.accessReviewQueryScope",
"query": "/groups/<groupid>/transitiveMembers",
"queryType": "MicrosoftGraph"
},
"reviewers": [
{
"query": "/groups/<groupid>/owners",
"queryType": "MicrosoftGraph"
}
],
"settings": {
"mailNotificationsEnabled": true,
"reminderNotificationsEnabled": true,
"justificationRequiredOnApproval": true,
"defaultDecisionEnabled": false,
"defaultDecision": "None",
"instanceDurationInDays": 3,
"recommendationsEnabled": false,
"recurrence": {
"pattern": {
"type": "weekly",
"interval": 1
},
"range": {
"type": "noEnd",
"startDate": "2022-02-25T12:02:30.667Z"
}
}
}
}
Any ideas?
I will answer my own question.
I see now in the browser when I create an access review with two groups in scope that it actually creates two separate access reviews, one for each group. It seems that it's not possible to create one access review for multiple groups when posting this.
Related
I have a Azure storage account and in that there are multiple containers. I need to give access to particular container using security group ( /via access package).
Considering least privileged access in Azure, how can I enable giving access to my Data storage/container ( for example, blob) so that users can PIM up before accessing a specific container ( e.g. Blob) from Azure?
The roles that needs to go via Privileged Identity Management(PIM) could be:
Storage blob data reader
Storage blob date contributor
I was going via MS tutorials here( Link1, link2, Link3 ). However, unable to figure out the right and best approach for this. Is there any other step by step guide? Thanks
To start with you can ,use the Azure portal itself for the Storage Blob Data Contributor ,Storage Blob Data Owner where Azure role assignment condition can be done as an additional check that you can optionally add to your role assignment to provide more fine-grained access control.
Add or edit Azure role assignment conditions :PORTAL which is preview account.
and yes the scope can be container level.
Click Add condition to further refine the role assignments based on storage attributes.
You can then add resource and conditions like ex: Ifselected user tries to read a blob without the Project=Cascade tag, access will not be allowed.
• Resource indicates that the attribute is on the resource, such as container name. You have to type the name and drop down wont be listed to select the blob.
This can be done from ARM template also.
The following template shows how to assign the Storage Blob Data Reader role with a condition. The condition checks whether the container name equals 'blobs-example-container' which can be given with resource #Resource[Microsoft.Storage/storageAccounts/blobServices/containers:name] StringEquals 'blobs-example-container'
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"metadata": {
"description": "Principal ID to assign the role to"
}
},
"principalType": {
"type": "string",
"metadata": {
"description": "Type of principal"
}
},
"roleAssignmentGuid": {
"type": "string",
"defaultValue": "[newGuid()]",
"metadata": {
"description": "New GUID used to identify the role assignment"
}
}
},
"variables": {
"StorageBlobDataReader": "[concat(subscription().Id, '/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')]" // ID for Storage Blob Data Reader role, but can be any valid role ID
},
"resources": [
{
"name": "[parameters('roleAssignmentGuid')]",
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2020-04-01-preview", // API version to call the role assignment PUT.
"properties": {
"roleDefinitionId": "[variables('StorageBlobDataReader')]",
"principalId": "[parameters('principalId')]",
"principalType": "[parameters('principalType')]",
"description": "Role assignment condition created with an ARM template",
"condition": "((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'})) OR (#Resource[Microsoft.Storage/storageAccounts/blobServices/containers:name] StringEquals 'blobs-example-container'))", // Role assignment condition
"conditionVersion": "2.0"
}
}
]
}
But additionally to secureand limit user with a time-bound setting, approval workflow, audit trail, and so on along with fine-grained conditions you may need to use PIM and add additional properties like scheduleInfo, admin access
just like the one you have linked to here using portal or ARM pim-resource-roles-assign-roles
{
"properties": {
"principalId": "a3bb8764-cb92-4276-9d2a-ca1e895e55ea",
"roleDefinitionId": "/subscriptions/dfa2a084-766f-4003-8ae1-c4aeb893a99f/providers/Microsoft.Authorization/roleDefinitions/c8d4ff99-41c3-41a8-9f60-21dfdad59608",
"requestType": "AdminAssign",
"scheduleInfo": {
"startDateTime": "2022-07-05T21:00:00.91Z",
"expiration": {
"type": "AfterDuration",
"endDateTime": null,
"duration": "P365D"
}
},
"condition": "#Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase 'foo_storage_container'",
"conditionVersion": "1.0"
}
}
See Schedule Requests
You can check the syntax formats here
You can also make use of storage-sas for container level access control where you can set expiry time and invoke permissions for those s=resources.
Reference:Azure attribute-based access control (Azure ABAC)
I'm working on testing out using GitHub and GitHub Actions to do policy as code for Azure. I have been successful in following the tutorials that Microsoft has where you export the policy you want to manage to GitHub from the Azure portal. This works fine and I'm able to edit and run the workflows to update Azure with changes to policies.
What I'd like to know is, can you create NEW policies in GitHub and push them to Azure? It seems that you need to first export a custom policy from Azure into GitHub, then you can manage that policy. I say this because when I create a new policy and a workflow for that policy I get the following error in GitHub from the workflow:
> Did not find any policies to create/update. No policy files match the
> given patterns or no changes were detected.
The policy I have in the folder is called "policy.json"
I also see:
Error occured while reading policy in path :
policies/global_tagging_policy. Error : Error: Path :
policies/global_tagging_policy. Property id is missing from the policy
definition. Please add id to the definition file.
That leads me to believe I need an ID prior to being able to push a policy, that says to me that Azure must have assigned one... I can't just make one up.
This is the policy I'm trying to push - just a tagging policy for testing, I don't have an ID in there, I read that you don't need to add one... that Azure would do it for you. Am I wrong?:
{
"properties": {
"displayName": "test-policy",
"description": "this is a test policy",
"mode": "indexed",
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag Name",
"description": "Name of the tag, such as 'environment'"
}
},
"tagValue": {
"type": "String",
"metadata": {
"displayName": "Tag Value",
"description": "Value of the tag, such as 'production'"
}
}
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
},
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
}
]
},
"then": {
"effect": "modify",
"details": {
"roleDefinitionIds": [
"/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
],
"operations": [
{
"operation": "add",
"field": "[concat('tags[', parameters('tagName'), ']')]",
"value": "[parameters('tagValue')]"
}
]
}
}
}
}
This tripped me up too so I did some exploring of the APIs and files. I've written about this in greater detail here.
To create a custom Policy, Initiative or Assignment file using GitHub Actions you'll need to generate an id, name & type at the root of the JSON.
The name property needs to be unique at the scope you assign it, I use GUIDs for this but you don't have to. Bear in mind if you define/assign at the Management Group scope then the name needs to be 24 characters or less.
The type denotes the type of file, the options are:
Microsoft.Authorization/policyDefinitions --> Policies
Microsoft.Authorization/policySetDefinitions --> Initiatives
Microsoft.Authorization/policyAssignments --> Assignments
The id is a bit more complex, and is a concatenation of the name and type values with other values mixed in.
The prefix depends on the scope which you want to define your Policy/Initiative/Assignment.
For Management Groups it would be:
/providers/Microsoft.Management/managementGroups/00000000-0000-0000-0000-000000000000
Subscriptions would be:
/subscrptions/00000000-0000-0000-0000-000000000000
Resource Groups:
/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup
This is followed by: providers in all cases
Next is the type value, so whatever you've used for that use again here.
Finally the last segment of the id is the same value you've used for the name property.
In one line that is
/{scope}/providers/{type}/{name}
So as an example:
Policy Definition scoped at a Management Group
{
"id": "/providers/Microsoft.Management/managementGroups/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/5f44e572-5d2d-4edf-9d61",
"name": "5f44e572-5d2d-4edf-9d61",
"type": "Microsoft.Authorization/policyDefinitions",
"properties":{}
}
Policy Definition scoped at a Subscription
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/8e4a8c58-1938-4467-8698",
"name": "8e4a8c58-1938-4467-8698",
"type": "Microsoft.Authorization/policyDefinitions",
"properties":{}
}
Initiative scoped at a Management Group
{
"id": "/providers/Microsoft.Management/managementGroups/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policySetDefinitions/be09f23f-0252-4d8a-a805",
"name": "5f44e572-5d2d-4edf-9d61",
"type": "Microsoft.Authorization/policySetDefinitions",
"properties":{}
}
Initiative scoped at a Subscription
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policySetDefinitions/8e4a8c58-1938-4467-8698",
"name": "8e4a8c58-1938-4467-8698",
"type": "Microsoft.Authorization/policySetDefinitions",
"properties":{}
}
I've applied Azure policy which forces the user to assign a tag while creating a Resource Group.
When i create a new VM and then fill in all the fields, i create a new Resource Group in the same wizard and then click review and create button. This time azure policy is triggered properly and blocks me as the newly created RG is not created with tag.
But when I go to resource group policy and click on Add to create a new RG. that time i don't fill Tags then too policy doesn't get trigger.
I'm little surprise why the first time this policy is working but not the second time.
{
"if": {
"allOf": [
{
"field": "tags",
"exists": "false"
},
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
}
]
},
"then": {
"effect": "deny"
}
}
The discrepancy you are experiencing is caused by differences in the JSON representation of the resource group.
Depending on what you click in the portal, the resource group JSON may not have a tags property, e.g.:
{
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/foo",
"name": "foo",
"location": "eastus",
"properties": {
"provisioningState": "Succeeded"
}
}
Other times it may be created with an empty tags property, e.g:
{
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/foo",
"name": "foo",
"location": "eastus",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {}
}
The "exists": "false" condition in your policy rule will only trigger if the "tags" property is either missing or null, so a resource group with "tags": {} will bypass your policy even though it doesn't have any tags.
Seems figure it out, it is not related to the Azure policy, your policy should work fine, it may be a bug of the blade of creating the resource group in the portal.
I try to create a resource group via powershell several times, the policy works fine.
My test policy:
If it is necessary, you could open an issue in the Github.
I'm trying to force anyone that is provisioning resources or services in Azure to only be able to select a specific region(s). For example, when they provision a resource group, the dropdown only shows a specific region(s). I was hoping there is some global setting that will affect all users. We are also using Azure AD; does that help or matter? I tried searching the Azure docs and the PowerShell commands, but I just can't find any mention of this setting.
You could use Azure Policy to do it.
Here is a sample policy requires that all resources are deployed to the approved location, refer to this link, you could try to deploy with portal or with powershell.
This policy requires that all resources are deployed to the approved locations. You specify an array of approved locations.
Sample template:
{
"properties": {
"displayName": "Allowed locations",
"policyType": "BuiltIn",
"description": "This policy enables you to restrict the locations your organization can specify when deploying resources. Use to enforce your geo-compliance requirements.",
"parameters": {
"listOfAllowedLocations": {
"type": "Array",
"metadata": {
"description": "The list of locations that can be specified when deploying resources.",
"strongType": "location",
"displayName": "Allowed locations"
}
}
},
"policyRule": {
"if": {
"not": {
"field": "location",
"in": "[parameters('listOfAllowedLocations')]"
}
},
"then": {
"effect": "Deny"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "e56962a6-4747-49cd-b67b-bf8b01975c4c"
}
is there any way how to restrict access or buy permissions at Azure Marketplace?
You can create a policy like the one below to restrict compute resources from a specific publisher -
{
"policyRule": {
"if": {
"allOf": [
{
"field": "Microsoft.Compute/imagePublisher",
"match": "[parameters('NotAllowedImage')]"
}
]
},
"then": {
"effect": "Deny"
}
},
"parameters": {
"NotAllowedImage": {
"type": "String",
"metadata": {
"displayName": "Not Allowed Image",
"description": "Not Allowed Image for Virtual Machine/Compute"
}
}
},
"metadata": {
"category": "Compute"
}
}
When you assign this image to a subscription or a resource group then at the time you will be asked to enter a value for the image name you would like to restrict , please enter "checkpoint" as your publisher name as this is the one you want to restrict. Save the assignment.
Now once you create a vm/compute resource from "checkpoint" this would fail the validation step as the policy would not allow to create such vm/compute resource.
The Category of the check point resources I see in market place is compute only.
We might not have restrictions on what we can choose from market place but we can utilize azure policy for certain resource regulation/compliance.
These policies would help enforce different rules over your resources(VM'S , VM-SKU , Network , Storage etc.). If you need resources created to stay compliant with your company standards/service level agreements.
Whenever we create resource which has policy tied to it these are evaluated and scanned for compliance with that policy.
More info here - https://learn.microsoft.com/en-us/azure/azure-policy/azure-policy-introduction