Last active
April 7, 2024 21:06
-
-
Save jlucaspains/8cbcb641a5ebc40a027956f94127f0a7 to your computer and use it in GitHub Desktop.
Create app registrations and add roles bound to azure entra groups
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"requestedAccessTokenVersion": 2, | |
"oauth2PermissionScopes": [ | |
{ | |
"id": "332a3ddb-38d8-4c69-a59a-1ea9b2058685", | |
"adminConsentDescription": "Read and write information about people", | |
"adminConsentDisplayName": "Read and write information about people", | |
"isEnabled": true, | |
"type": "User", | |
"userConsentDescription": "Read and write information about people", | |
"userConsentDisplayName": "Read and write information about people", | |
"value": "api-read-write" | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"allowedMemberTypes": [ | |
"User" | |
], | |
"description": "Can use all app features including write capabilities", | |
"displayName": "Administrator", | |
"id": "25909a57-ce45-49d3-b1f3-4b6f3d03d15a", | |
"isEnabled": true, | |
"origin": "Application", | |
"value": "Administrator" | |
}, | |
{ | |
"allowedMemberTypes": [ | |
"User" | |
], | |
"description": "Can configure aspects the application but generally not make administrative changes", | |
"displayName": "Developer", | |
"id": "07470a96-716a-4688-92fd-6fb452f81202", | |
"isEnabled": true, | |
"origin": "Application", | |
"value": "Developer" | |
}, | |
{ | |
"allowedMemberTypes": [ | |
"User" | |
], | |
"description": "Can view data and perform user level actions but not make administrative changes", | |
"displayName": "User", | |
"id": "3e87b7be-a276-4e85-add7-974e0d29fed8", | |
"isEnabled": true, | |
"origin": "Application", | |
"value": "User" | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding()] param () | |
$AppNames = @( | |
"OrdersApi", | |
"PeopleApi" | |
) | |
$Envs = @( | |
"dev", | |
"qa" | |
) | |
foreach ($AppName in $AppNames) { | |
Write-Host "Processing $($AppName)..." | |
foreach ($Env in $Envs) { | |
$FullAppName = "$($AppName)-$($Env)" | |
Write-Host "Processing $FullAppName..." | |
$appObjectId = (az ad app list --display-name $FullAppName --query "[0].id" -o tsv) | |
# If the app is not found, create it. | |
# This is the place to add any special configuration needed for a new app registration | |
if ($null -eq $appObjectId) { | |
$appObjectId = (az ad app create --display-name $FullAppName --sign-in-audience AzureADMyOrg --identifier-uris "api://$($FullAppName).lpains.net" --query "id" -o tsv) | |
# Ensure the api section is set correctly | |
az ad app update --id $appObjectId --set api=@appApi.json | |
az ad app permission add --id $appObjectId --api 00000003-0000-0000-c000-000000000000 --api-permissions e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope | |
} | |
# Find the enterprise app service principal object id | |
$appSPObjectId = (az ad sp list --display-name $FullAppName --query '[0].id' -o tsv) | |
if ($null -eq $appSPObjectId) { | |
$appSPObjectId = (az ad sp create --id $appObjectId --query '[0].id' -o tsv) | |
} | |
Write-Host "App Object Id: $appObjectId" | |
Write-Host "App Service Principal Object Id: $appSPObjectId" | |
} | |
Write-Host "Finished procesing $($AppName). It may take a few minutes for the changes to take effect." | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding()] param () | |
$AppNames = @( | |
"OrdersApi", | |
"PeopleApi" | |
) | |
$Envs = @( | |
"dev", | |
"qa" | |
) | |
foreach ($AppName in $AppNames) { | |
Write-Host "Processing $($AppName)..." | |
foreach ($Env in $Envs) { | |
$FullAppName = "$($AppName)-$($Env)" | |
Write-Host "Processing $FullAppName..." | |
$appObjectId = (az ad app list --display-name $FullAppName --query "[0].id" -o tsv) | |
$appSPObjectId = (az ad sp list --display-name $FullAppName --query '[0].id' -o tsv) | |
Write-Verbose "App Object Id: $appObjectId" | |
Write-Verbose "App Service Principal Object Id: $appSPObjectId" | |
if ($null -eq $appObjectId -or $null -eq $appSPObjectId) { | |
Write-Host "App registration not found. Skipping..." | |
continue; | |
} | |
$jsonData = Get-Content -Path "./appRoles.json" | ConvertFrom-Json | |
# The appRoles file may contain a subset of the roles | |
# we will create a unique list of roles already in the app registration and the roles in the file | |
Write-Host "Creating unique list of roles to update..." | |
$existingAppRegRolesJson = (az ad app list --display-name $FullAppName --query "[0].appRoles") | |
Write-Verbose ($existingAppRegRolesJson | ConvertTo-Json) | |
$existingAppRegRoles = $existingAppRegRolesJson | ConvertFrom-Json | |
$mergedUniqueRoles = $existingAppRegRoles + $jsonData | Sort-Object -Property Id -Unique | |
$appRoles = $mergedUniqueRoles | ConvertTo-Json | |
Write-Verbose $appRoles | |
$appRoles > "./TempRoles.json" | |
# Apply the unique set of app roles to the app registration | |
Write-Host "Adding app registration roles..." | |
az ad app update --id $appObjectId --app-roles "./TempRoles.json" | |
# Find existing role assignments in the enterprise app | |
$existingRoles = (az rest -m GET -u "https://graph.microsoft.com/v1.0/servicePrincipals/$appSPObjectId/appRoleAssignedTo") | ConvertFrom-Json | |
Write-Verbose $existingRoles | |
foreach ($role in $jsonData) { | |
$existingRole = $existingRoles.value | Where-Object { $_.appRoleId -eq $role.id } | |
# No reason to apply an existing role assignment again | |
if ($null -ne $existingRole) { | |
Write-Verbose $existingRole | |
Write-Host "Binding already exist between $($role.Value) and group prefix-$($Env)-$($role.Value)..." | |
continue; | |
} | |
# Find the Azure Entra group using a convention approach of prefix-environment-role | |
Write-Host "Binding $($role.Value) to group blog-$($Env)-$($role.Value)..." | |
$RoleGuid = $role.id | |
$groupId = (az ad group list --display-name "blog-$($Env)-$($role.Value)" --query "[0].id" -o tsv) | |
$postBody = "{\""principalId\"": \""$groupId\"", \""resourceId\"": \""$appSPObjectId\"", \""appRoleId\"": \""$RoleGuid\""}" | |
Write-Verbose $postBody | |
# Create the role assignment between the group and the app role | |
az rest -m POST -u "https://graph.microsoft.com/v1.0/servicePrincipals/$appSPObjectId/appRoleAssignments" -b $postBody --headers "Content-Type=application/json" | |
} | |
} | |
Write-Host "Finished procesing $($AppName)" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment