I'm trying to provision azuread_claims_mapping_policy
but it fails due to missing permissions.
│ Error: retrieving Claims Mapping Policy with object ID: "<GUID HERE>"
│
│ with azuread_claims_mapping_policy.integration_claims_mapping[0],
│ on active_directory.tf line 54, in resource "azuread_claims_mapping_policy" "integration_claims_mapping":
│ 54: resource "azuread_claims_mapping_policy" "integration_claims_mapping" {
│
│ ClaimsMappingPolicyClient.BaseClient.Get(): unexpected status 403 with
│ OData error: Authorization_RequestDenied: Insufficient privileges to
│ complete the operation.
The code is executed in context of Managed Identity
As it is written here in documentation:
When authenticated with a service principal, this resource requires the following application roles: Policy.ReadWrite.ApplicationConfiguration and Policy.Read.All
When authenticated with a user principal, this resource requires one of the following directory roles: Application Administrator or Global Administrator
I added Application Administrator
role to that identity. But it failed with te result above. It passes with Global Administrator
, but I would prefer to avoid this.
Is there a way to provision azuread_claims_mapping_policy
without Global Administrator
role?
Here is the code I used:
locals {
entity_ids = {
"dev" : ["entity-id"],
}
redirect_uris = {
"dev" : ["redirect-uri"],
}
}
data "azuread_client_config" "current" {}
resource "azuread_application" "saml_integration" {
count = var.env == "prod" ? 0 : 1
display_name = "SAML integration - ${upper(var.env)}"
owners = [data.azuread_client_config.current.object_id]
identifier_uris = local.entity_ids[var.env]
web {
redirect_uris = local.redirect_uris[var.env]
}
feature_tags {
enterprise = true
gallery = false
custom_single_sign_on = true
}
app_role {
allowed_member_types = ["Application", "User"]
description = "Default role for standard users used for SAML integration"
display_name = "IntegrationUser"
enabled = true
id = "GUID HERE"
value = "IntegrationUser"
}
}
resource "azuread_service_principal" "saml_integration_service_principal" {
count = var.env == "prod" ? 0 : 1
application_id = azuread_application.saml_integration[0].application_id
app_role_assignment_required = false
owners = [data.azuread_client_config.current.object_id]
use_existing = true
preferred_single_sign_on_mode = "saml"
feature_tags {
enterprise = true
gallery = false
custom_single_sign_on = true
}
}
resource "azuread_service_principal_token_signing_certificate" "signing_certificate" {
service_principal_id = azuread_service_principal.saml_integration_service_principal[0].id
}
resource "azuread_service_principal_claims_mapping_policy_assignment" "app" {
count = var.env == "prod" ? 0 : 1
claims_mapping_policy_id = azuread_claims_mapping_policy.integration_claims_mapping[0].id
service_principal_id = azuread_service_principal.saml_integration_service_principal[0].id
}
resource "azuread_claims_mapping_policy" "integration_claims_mapping" {
count = var.env == "prod" ? 0 : 1
display_name = "Claims Mapping for ${azuread_application.saml_integration[0].display_name}"
definition = [
jsonencode(
{
... hidden
)
]
}
resource "azuread_user" "test_user" {
count = var.env == "prod" ? 0 : 1
user_principal_name = "test-saml-user-${var.env}@contoso.com"
mail = "test-saml-user-${var.env}@contoso.com"
display_name = "Test Contoso SSO User ${var.env}"
given_name = "Test"
surname = "User ${upper(var.env)}"
password = "SUBERPASSWORD"
}
resource "azuread_group" "test_app_users_group" {
count = var.env == "prod" ? 0 : 1
display_name = "Test SAML integration - ${upper(var.env)}"
owners = [data.azuread_client_config.current.object_id]
security_enabled = true
members = [
azuread_user.test_user[0].object_id
]
}
resource "azuread_app_role_assignment" "test_user_group_assignment" {
app_role_id = azuread_service_principal.saml_integration_service_principal[0].app_role_ids["IntegrationUser"]
principal_object_id = azuread_group.test_app_users_group[0].object_id
resource_object_id = azuread_service_principal.saml_integration_service_principal[0].object_id
}
Please note that some values are hidden to do not expose confidential data.
I had add following permissions:
Application.ReadWrite.All
Policy.ReadWrite.ApplicationConfiguration
Policy.Read.All
But since there is no possibility to do this via Portal (for managed identities) I used script from this article.
$TenantID = "provide the tenant ID"
$GraphAppId = "00000003-0000-0000-c000-000000000000"
$DisplayNameOfMSI = "Provide the Logic App name"
$PermissionNames = @("Application.ReadWrite.All", "Policy.ReadWrite.ApplicationConfiguration", "Policy.Read.All")
# Install the module
Install-Module AzureAD
Connect-AzureAD -TenantId $TenantID
$MSI = (Get-AzureADServicePrincipal -Filter "displayName eq '$DisplayNameOfMSI'")
Start-Sleep -Seconds 10
$GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'"
foreach ($PermissionName in $PermissionNames) {
$AppRole = $GraphServicePrincipal.AppRoles | Where-Object { $_.Value -eq $PermissionName -and $_.AllowedMemberTypes -contains "Application" }
New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id
}
Write-Output "Permissions added successfully."