microsoftgraph / msgraph-bicep-types

Repo contains Microsoft Graph resource types to integrate with bicep templates.
MIT License
46 stars 7 forks source link

Simplify applications' permissionScopes (OAuth2 scopes) and appRoles updates via Bicep #197

Open dkershaw10 opened 1 day ago

dkershaw10 commented 1 day ago

Is your feature request related to a problem? Please describe. Updating the permissionScopes or appRoles collections is extremely cumbersome on an application registration. We've seen multiple issues filed for this. While it does conform to desired state configuration, it's unintuitive that to remove a permission scope or app role record from the collection it cannot simply be removed from the Bicep file declaration and deployed. Instead it's a 2-step process where:

  1. the existing collection must be updated to mark any records (that need to be deleted) as disabled ("isEnabled": false), and the template deployed
  2. one deployed, the collection can be updated to remove the disabled records, and the template deployed

This 2-step process is particularly cumbersome for any pipeline automations.

Describe the solution you'd like Investigate whether the Graph Bicep extension layer can hide this complexity by offering a more straightforward desired state configuration solution. This solution would allow the template author to simply update the permissionScopes and appRoles collections removing any records that the author no longer needs.

Additional context It's possible that this safeguard was originally introduced in the REST layer to prevent accidental deletion of records in these collections, for customers who might have expected these collections to have "append semantics". This doesn't seem as desirable in the Bicep layer.

dkershaw10 commented 1 day ago

cc: @christianacca

christianacca commented 1 day ago

Thanks @dkershaw10

Anttarax commented 21 hours ago

Yes, its a real problem. I had to write a seperated powershell script called RrunBeforeAppregDeploy.ps1 This script sets all scopes and roles to false.

# Import required modules
Import-Module Microsoft.Graph.Applications

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Application.ReadWrite.All"

# Predefined list of application registration Object IDs
$appObjectIds = @(
    "[APP_ID_1]", #app-name-1
    "[APP_ID_2]", #app-name-2
    "[APP_ID_3]", #app-name-3
    "[APP_ID_4]", #app-name-4
    "[APP_ID_5]", #app-name-5
    "[APP_ID_6]", #app-name-6
    "[APP_ID_7]", #app-name-7
    "[APP_ID_8]"  #app-name-8
)

# Process all specified application registrations
foreach ($objectId in $appObjectIds) {
    Write-Host "Processing: $objectId"

    try {
        # Get application directly by Object ID
        $app = Get-MgApplication -ApplicationId $objectId

        if ($app) {
            # Modify API permissions (oauth2PermissionScopes)
            $updatedApi = @{}
            if ($app.Api) {
                $updatedApi = $app.Api
                if ($updatedApi.Oauth2PermissionScopes) {
                    $updatedApi.Oauth2PermissionScopes = $updatedApi.Oauth2PermissionScopes | ForEach-Object {
                        $_.IsEnabled = $false
                        $_
                    }
                }
            }

            # Modify app roles
            $updatedAppRoles = @()
            if ($app.AppRoles) {
                $updatedAppRoles = $app.AppRoles | ForEach-Object {
                    $_.IsEnabled = $false
                    $_
                }
            }

            # Update application
            Update-MgApplication -ApplicationId $objectId -Api $updatedApi -AppRoles $updatedAppRoles

            Write-Host "Application successfully updated: $objectId"
        } else {
            Write-Host "No application found with this Object ID: $objectId"
        }
    }
    catch {
        Write-Host "Error occurred while processing application: $objectId"
        Write-Host $_.Exception.Message
    }
}

# Disconnect
Disconnect-MgGraph