Give Terraform Service Principal Contributor but remove from Key Vault - azure

We are building a solution in Azure Government and we will be using Terraform to deploy the solution. Seems the preferred method is to create a Service Principal for Terraform with the Service Principal having the Contributor role scoped to the subscription.
The one issue with this we are looking to solve is that this gives the Service Principal management plane access to the Key Vault...since it is in the subscription. With Contributor role, the service principal is not able to create new access policies (assign itself or others permissions to the data plane) but we are looking for a way that can remove the service principal from having any management plane permissions.
We have tried putting a ReadOnly lock on the Key Vault before creating the Service Principal but the lock does not stop the service principal from getting the Contributor permissions on the Key Vault.
Outside of creating a new role that has Contributor for everything EXCEPT for Key Vault, does anyone have any creative ideas that might help achieve this?

Yes, the root cause of all security issues is that the Service Principal's contributor role assignment is at the subscription level/scope, which enables it to do quite damage specially if multiple applications are deployed to the same subscription (e.g. delete any resource group).
One approach would be:
Provision one resource group for the Azure Key Vault specific to the application and region (the latter in case of geo-distributed applications).
Provision the Azure Key Vault on the resource group created on the previous step.
In our case, the Security Office was responsible for the first 2 steps, where they had monitoring (e.g. email, text-messages, etc.) for any change in the Azure Key Vault (e.g. new keys/secrets/certificates added/deleted/changed, permission changes, etc.).
Provision a second resource group, which will serve as a container for the application components (e.g. Azure Function, Azure SQL Server/Database, Azure Service Bus Namespace/Queue, etc.).
Create the Service Principal and assign the Contributor role to the
application resource group only, for example:
scope =
/subscriptions/{Subscription Id}/resourceGroups/{Resource Group
Name}
Find a sample PS script to provision a Service Principal with custom scope at https://github.com/evandropaula/Azure/blob/master/ServicePrincipal/PS/Create-ServicePrincipal.ps1.
Give appropriate permissions for the Service Principal in the Azure
Key Vault. In our case, we decided to have separate Service
Principal accounts for deployment (Read-Write permissions on keys/secrets/certificates) and runtime (Read-Only permissions on keys/secrets/certificates);
Find a sample PS script to set Service Principal permission on an Azure Key Vault at https://github.com/evandropaula/Azure/blob/master/KeyVault/PS/Set-ServicePrincipalPermissions.ps1.
Having that said, there are lots of inconveniences with this approach, such as:
The process (e.g. via runbook) to provision the Azure Key Vault (including its resource group) and the application resource group will be outside of the main Terraform template responsible for the application components, which requires coordination with different teams/processes/tools/etc.
Live site involving connectivity often involves coordination among multiple teams to ensure RTO and MTTM (Mean Time To Mitigate) goals are achieved.
The Service Principal will be able to delete the application specific resource group when terraform destroy is executed, but it will fail to recreate it when running terraform apply after that due to lack of permission at the subscription level/scope. Here is the error:
provider.azurerm: Unable to list provider registration status, it is possible that this is due to invalid credentials or the service principal does not have permission to use the Resource Manager API, Azure error: resources.ProvidersClient#List: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client '' with object id '' does not have authorization to perform action 'Microsoft.Resources/subscriptions/providers/read' over scope '/subscriptions/{Subscription Id}'.".
Yeah, I know, this is a long answer, but the topic usually requires lots of cross-team discussions/brainstorming to make sure the security controls established by the Security Office are met, Developer productivity is not affected to the point that it will impact release schedules and RTO/MTTM goals are met. I hope this helps a bit!

Related

Block inherited permissions to azure resource group

My subscription has a service principal that must have contributor rights. These rights will be inherited by all resource groups. In one resource group that has been established for over a year. for security reasons, this service principal must be prohibited from doing anything. The maximum allowed is reading. I tried using https://learn.microsoft.com/en-us/azure/governance/blueprints/overview but apparently I misconfigured or just doesn't work in my case. Since under the credential of this service principal, I was able to delete the test storage account. Could you please help me set up these policies to see if it's possible or not? Thank you.

Can't access resource group in Azure, while having Contributor role for it

I've been given access to a resource group in Azure, but still get 401 page while trying to access it or any resource in that resource group. I have role assigned to me only in a resource group, not subscription (maybe this can be the reason?)
Type of my user: Guest
Role for a resource group: Contributor
Contributor role gives full access, except ability to assign roles to other users.
Also, according to docs
Guests can be added to administrator roles, which grant them full read
and write permissions
What can be the problem?
This is the page I get when trying to access resource group or any of it resource:
Azure Resource Manager sometimes caches configurations and data to improve performance. When you assign roles or remove role assignments, it can take up to 30 minutes for changes to take effect. If you are using the Azure portal, Azure PowerShell, or Azure CLI, you can force a refresh of your role assignment changes by signing out and signing in. If you are making role assignment changes with REST API calls, you can force a refresh by refreshing your access token.
Source: Troubleshoot Azure RBAC - Role assignment changes are not being detected
Another option would be to visit the preview portal. Since this is a different website, you will get a new token which reflects the latest state.

Service principal or Managed Identity

I have a client that can only give me full access to one or two resource groups.
I need to deliver some prescripted terraform resources that contain the need for a service principal.
Can you lock an SP to a resource group? The subscription itself is a production subscription so they want to know if you can tie down using role base access just to that group.
Or should I be create a MI account?
Can you lock an SP to a resource group?
You most certainly can. Azure Role-based access control is very granular and you can apply access control at any level (management group, subscription, resource group or even at individual resource).
Please see this for more details: https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-steps.

The client with object id does not have authorization to perform action taggedTrafficConsumers/validate

When using Azure Key Vault management REST API or cmdlet Add-AzureRmKeyVaultNetworkRule to allow a virtual network to access a key vault, I get the following error:
The client '{guid}' with object id '{guid}' does not have authorization to perform
action 'microsoft.network/virtualnetworks/taggedTrafficConsumers/validate/action'
over scope '/subscriptions/{guid}/resourcegroups/{resource-group}/providers/microsoft.network/virtualnetworks/{vnet-name}/taggedTrafficConsumers/Microsoft.KeyVault'
What is wrong?
Your subscription is not giving Microsoft.KeyVault resource provider permission to access Microsoft.Network resources. The fix is to register your subscription to Microsoft.KeyVault again:
Register-AzureRmResourceProvider -ProviderNamespace Microsoft.KeyVault
This will add required permissions for Microsoft.KeyVault and Microsoft.Network integrations, including the ability to limit access to a given Virtual Network.
For more information: https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-supported-services
This are the steps required to solve it:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types#azure-portal
You just need to register the resource provider in the subscription, this doesn't only happens with Key Vault, my issue was with Sql Server as well :)
So I leave this answer here in case someone else needs it
This feels like a bug/limitation in both the Azure Portal and Azure CLI. We ran into this when trying to allow a subnet of a VNET in subscription X to access a storage account in subscription Y.
For us, the workaround was to look-up the name of the service principal that was mentioned in the error in our Azure AD directory using the "Search your tenant" box on the "Overview" tab of the directory (NOT the subscription but the Azure AD directory for the tenant). The name of the SP turned out to be "Storage Resource Provider" (yours may be different, so that's why you need to look it up in Azure AD), so we granted that SP "Owner" role (temporarily) in the other subscription. Then provisioning worked!
There should be a finer-grained set of permissions you need to grant than just "Owner" but when we granted just the "validate" permission, we got a new error:
Failed to save firewall and virtual network settings for storage account 'XXX'. Error: An operation is currently performing on this storage account that requires exclusive access.
Also experienced this error when adding a vnet to a storage-account in another subscription.
Fixed by adding a storage-account to the subscription using the portal. Then the vnet could be added to the storage-account.
Note: the result is the same as #fernacolo does with a powershell command.

The client with object id does not have authorization to perform action 'Microsoft.DataFactory/datafactories/datapipelines/read' over scope

I was trying to invoke data factory pipeline from azure function programmatically. Its throwing following error.
link:
http://eatcodelive.com/2016/02/24/starting-an-azure-data-factory-pipeline-from-c-net/
AuthorizationFailed: The client 'XXXX-XXXXX-XXXX' with object id 'XXX829e05'XXXX-XXXXX' does not have authorization to perform action
'Microsoft.DataFactory/datafactories/datapipelines/read' over scope
'/subscriptions/XXXXXX-4bf5-84c6-3a352XXXXXX/resourcegroups/fffsrg/providers/Microsoft.DataFactory/datafactories/ADFTestFFFS/datapipelines/ADFTutorialPipelineCustom'.
tried to search similar issues, but none of the search result gave me solution to my problem, Can you please guide us what could be the issue?
Objective is to, run data factory pipeline whenever file being added to blob. so to achieve the result we are trying to invoke data factory pipeline from azure function using blob trigger.
Step 1: login to your azure portal
Step 2: find Subscriptions in left side menu bar and click.
step 3: Click on Access Control IAM and then click on Add.
Step 4: In Add Permission window, select contributor for role. In select input box, type the app name you created in Azure AD (Created in Azure Active Directory)and select it. In my case I created Azure Resource Management.
Step 5:After you have given successful permission, click on Refresh in your subscription window and you will see your app showing in the list. See below example.
SEE Common problem when using Azure resource groups & RBAC
https://blogs.msdn.microsoft.com/azure4fun/2016/10/20/common-problem-when-using-azure-resource-groups-rbac/
This issue is more likely to happen in newer subscriptions and usually happens if a certain resource type has never been created before in that subscription.
Subscription admins often fix this issue by granting resource group owners contributor rights on the subscription level which contradicts with their strategy of isolating access down to the level of resource group level not the subscription level.
Root cause
Some admins say, that some resources require access to the subscription level to be able to create these resources and that ‘owner’ rights on a resource group level is not sufficient. That is not true.
Let’s take a step back to understand how this all works first.
To provision any resources in azure (using the resource manager model) you need to have a resource provider that supports the creation of that resource. For example, if you will provision a virtual machine, you need to have a ‘Microsoft.Compute’ resource provider available in the subscription first before you can do that.
Resource providers are registered on the level of the subscription only.
Luckily, the Azure Resource Manager (ARM) is intelligent enough to figure that out for you. When a new Azure resource gets provisioned, if the resource provider required for that resource type is not registered in the subscription yet, ARM will attempt to register it for you. That action (resource provider registration) requires access to the subscription level.
By default, any new azure subscription will be pre-registered with a list of commonly used resource providers. The resource provider for IoTHub for instance, is not one of them.
When a user is granted owner rights only on a specific resource group, if that user tries to provision a resource that requires registering a resource provider for the first time, that operation will fail. That is what happened in our case above when trying to provision IoThub.
So the bottom line is, we DO NOT need to grant access permissions to the subscription level for users to be able to create resources like HDInsight, IotHub and SQLDW …etc within their resource groups that they have owner rights on, as long as the resource providers for these resources is already registered.
You get the error that you are not authorized to perform action 'Microsoft.DataFactory/datafactories/datapipelines/read' over scope of pipeline because you don't have the relevant permissions on the datafactory.
You either need to have "Contributor" /"DataFactoryContributor" permissions to create & manage data factory resources or child resources. More details of the azure RBAC roles in the following link:
https://learn.microsoft.com/en-us/azure/active-directory/role-based-access-built-in-roles
Since the customer is trying to use the ADF client from inside Azure Function, the recommendation is to use AAD application and service principal for authentication of ADF client. You can find the instructions for creating AAD application and service principal here:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal
Please follow the instructions on how to create the Active Directory application, service principal, and then assign it to the Data Factory Contributor role in the following link and the code sample for using service principal with ADF client.
We recently had this issue with the same message and found that it was caused by the user being logged in with a different subscription (we have 2). Using az login --subscription resolved the problem for us.
For anyone else running into a similar issue with the same error message - After "az login" I was recieving the same error when attempting to create a resource group as Owner, I solved this with:
az account set --subscription "Azure Subscription 1"
Basically it stems from the subscription not being set, you can find the details here:
https://learn.microsoft.com/en-us/cli/azure/manage-azure-subscriptions-azure-cli#get-the-active-subscription
Solution:
Step 1: Register an app in Azure Active directory.
Step 2: Assign 'Data Factory Contributor' role to the same app. we can achieve this by using power shell.
The below code works for me. Please try out in power shell after logged in with Azure credential.
Implementation:
Step 1: $azureAdApplication = New-AzureRmADApplication -DisplayName <AppName> -HomePage <URL> -IdentifierUris <URL with domain> -Password <Password>
Step 2: New-AzureRmRoleAssignment -RoleDefinitionName "Data Factory Contributor" -ServicePrincipalName $azureAdApplication.ApplicationId
Follow this post : https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal
In this post , Role is given as "Reader" which should be "Owner" instead otherwise it would give permission error on deployment.
I solved by following this post:
https://www.nwcadence.com/blog/resolving-authorizationfailed-2016
with the command in PowerShell:
Get-AzureRmResourceProvider -ListAvailable | Select-Object ProviderNamespace | Foreach-Object { Register-AzureRmResourceProvider -ProviderName $_.ProviderNamespace}
I solved by finding the Enterprise Application > Object ID.
(it is weird that it does not use App Reg > Application Id)
https://jeanpaul.cloud/2020/02/03/azure-data-factory-pipeline-execution-error/

Resources