microsoftgraph / msgraph-bicep-types

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

Adding API permissions using Bicep as configured permissions, not other permissions granted #182

Closed mikedzikowski closed 1 month ago

mikedzikowski commented 1 month ago

First time posting here, so please let me know if I need to make any changes to my question or add more details. I am unable to add API permissions as configured using the Bicep resource Microsoft.Graph/oauth2PermissionGrants@v1.0.

Example code used:

targetScope = 'tenant'

// entra-external-setup.bicep
extension microsoftGraph

param appName string = 'cspm'
param deployEnvironment string = 'lb'

var applicationRegistrationName = '${appName}-${deployEnvironment}-app-01'

var redirectUris = deployEnvironment == 'prod' 
  ? ['https://app.${appName}.io'] 
  : ['https://${applicationRegistrationName}.azurewebsites.net', 'https://localhost:44305']

resource microsoftGraphServicePrincipal 'Microsoft.Graph/servicePrincipals@v1.0' existing = {
  appId: '00000003-0000-0000-c000-000000000000'
}

resource applicationRegistration 'Microsoft.Graph/applications@v1.0' = {
  uniqueName: applicationRegistrationName
  displayName: applicationRegistrationName
  web: {
    redirectUris: [for item in redirectUris: '${item}/sigin-oidc']
    implicitGrantSettings: {
      enableIdTokenIssuance: true
    }
  }
  requiredResourceAccess: [
    {
     resourceAppId: microsoftGraphServicePrincipal.appId
     resourceAccess: [
       { 
         id: 'd07a8cc0-3d51-4b77-b3b0-32704d1f69fa', type: 'Scope' 
      }
     ]
    }
  ]
}

resource applicationRegistrationServicePrincipal 'Microsoft.Graph/servicePrincipals@v1.0' existing = {
  appId: applicationRegistration.appId
}

resource grants 'Microsoft.Graph/oauth2PermissionGrants@v1.0' = {
  clientId: applicationRegistrationServicePrincipal.id
  resourceId: microsoftGraphServicePrincipal.id
  consentType: 'AllPrincipals'
  scope: 'AccessReview.Read.All'
}

My goal is to use Bicep to add the API permissions, granted here: image

What am I missing? Thank you in advance!

jason-dou commented 1 month ago

@mikedzikowski Did you get any error when deploying the example template above? Could you share the deployment correlation Id, error message, MS Graph client request id, and timestamp? Were you using an interactive flow (with signed-in user) or automation (with application)?

mikedzikowski commented 1 month ago

Hi Jason,

Thank you for responding.

The deployment is successful, however the permissions are not granted as expected.

resource microsoftGraphServicePrincipal 'Microsoft.Graph/servicePrincipals@v1.0' existing = { appId: '00000003-0000-0000-c000-000000000000' }

This deployment was simply using Bicep that will later be expanded upon. The goal is to create a app registration, and apply API permissions and grant admin consent using bicep.

The permissions are added - but not consented or added as configured permissions.

image

DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
OK

Headers:
Cache-Control                 : no-cache
Pragma                        : no-cache
x-ms-ratelimit-remaining-subscription-reads: 248
x-ms-ratelimit-remaining-subscription-global-reads: 3748
x-ms-request-id               : c581d20a-b944-431e-bdd3-389efb86fc92
x-ms-correlation-request-id   : c581d20a-b944-431e-bdd3-389efb86fc92
x-ms-routing-request-id       : EASTUS:20241003T175918Z:c581d20a-b944-431e-bdd3-389efb86fc92
Strict-Transport-Security     : max-age=31536000; includeSubDomains
X-Content-Type-Options        : nosniff
X-Cache                       : CONFIG_NOCACHE
X-MSEdge-Ref                  : Ref A: 4EFAFF49D24E4E569E12480928935E63 Ref B: BL2AA2010204023 Ref C: 2024-10-03T17:59:18Z
Date                          : Thu, 03 Oct 2024 17:59:17 GMT

Body:
{
  "id": "/subscriptions/903292f9-92e0-4c39-a1c8-4f89fc0517fc/providers/Microsoft.Resources/deployments/Test",
  "name": "Test",
  "type": "Microsoft.Resources/deployments",
  "location": "eastus",
  "properties": {
    "templateHash": "16713000665181350799",
    "parameters": {
      "appName": {
        "type": "String",
        "value": "cspm"
      },
      "deployEnvironment": {
        "type": "String",
        "value": "lb"
      }
    },
    "mode": "Incremental",
    "provisioningState": "Succeeded",
    "timestamp": "2024-10-03T17:59:17.3959339Z",
    "duration": "PT4.5066414S",
    "correlationId": "12cbc018-b5ec-46e1-81c6-53cd5ff04fb7",
    "providers": [],
    "dependencies": [
      {
        "dependsOn": [
          {
            "symbolicName": "microsoftGraphServicePrincipal"
          }
        ],
        "symbolicName": "applicationRegistration"
      },
      {
        "dependsOn": [
          {
            "symbolicName": "applicationRegistration"
          }
        ],
        "symbolicName": "applicationRegistrationServicePrincipal"
      },
      {
        "dependsOn": [
          {
            "symbolicName": "applicationRegistrationServicePrincipal"
          },
          {
            "symbolicName": "microsoftGraphServicePrincipal"
          }
        ],
        "symbolicName": "grants"
      }
    ],
    "outputResources": []
  }
}

DEBUG: 5:59:18 PM - [ConfigManager] Got nothing from [DisplaySecretsWarning], Module = [], Cmdlet = []. Returning default value [True].
mikedzikowski commented 1 month ago

So a bit more testing, if admin consent is required - the permissions are set like so image

if admin consent is not required they are configured properly and set.

// entra-external-setup.bicep
extension microsoftGraph

param appName string
param deployEnvironment string

targetScope = 'tenant'

var applicationRegistrationName = '${appName}-${deployEnvironment}-app-01'

var redirectUris = deployEnvironment == 'prod' 
  ? ['https://app.${appName}.io'] 
  : ['https://${applicationRegistrationName}.azurewebsites.net', 'https://localhost:44305']

resource microsoftGraphServicePrincipal 'Microsoft.Graph/servicePrincipals@v1.0' existing = {
  appId: '00000003-0000-0000-c000-000000000000'
}

resource applicationRegistration 'Microsoft.Graph/applications@v1.0' = {
  uniqueName: applicationRegistrationName
  displayName: applicationRegistrationName
  web: {
    redirectUris: [for item in redirectUris: '${item}/sigin-oidc']
    implicitGrantSettings: {
      enableIdTokenIssuance: true
    }
  }
  requiredResourceAccess: [
    {
     resourceAppId: microsoftGraphServicePrincipal.appId
     resourceAccess: [
       { id: '7427e0e9-2fba-42fe-b0c0-848c9e6a8182', type: 'Scope' } // offline_access
       { id: '37f7f235-527c-4136-accd-4a02d197296e', type: 'Scope' } // openid
       {id: 'e4c9e354-4dc5-45b8-9e7c-e1393b0b1a20', type: 'Scope'} // AuditLog.Read.All
     ]
    }
  ]
}

resource applicationRegistrationServicePrincipal 'Microsoft.Graph/servicePrincipals@v1.0' = {
  appId: applicationRegistration.appId
}

resource grants 'Microsoft.Graph/oauth2PermissionGrants@v1.0' = {
  clientId: applicationRegistrationServicePrincipal.id
  consentType: 'AllPrincipals'
  resourceId: microsoftGraphServicePrincipal.id
  scope: 'openid offline_access AuditLog.Read.All'
}
mikedzikowski commented 1 month ago

This works:

// entra-external-setup.bicep
extension microsoftGraph

param appName string
param deployEnvironment string

targetScope = 'tenant'

var applicationRegistrationName = '${appName}-${deployEnvironment}-app-01'

var redirectUris = deployEnvironment == 'prod' 
  ? ['https://app.${appName}.io'] 
  : ['https://${applicationRegistrationName}.azurewebsites.net', 'https://localhost:44305']

resource microsoftGraphServicePrincipal 'Microsoft.Graph/servicePrincipals@v1.0' existing = {
  appId: '00000003-0000-0000-c000-000000000000'
}

resource applicationRegistration 'Microsoft.Graph/applications@v1.0' = {
  uniqueName: applicationRegistrationName
  displayName: applicationRegistrationName
  web: {
    redirectUris: [for item in redirectUris: '${item}/sigin-oidc']
    implicitGrantSettings: {
      enableIdTokenIssuance: true
    }
  }
  requiredResourceAccess: [
    {
     resourceAppId: microsoftGraphServicePrincipal.appId
     resourceAccess: [
       { id: '7427e0e9-2fba-42fe-b0c0-848c9e6a8182', type: 'Scope' } // offline_access
       { id: '37f7f235-527c-4136-accd-4a02d197296e', type: 'Scope' } // openid
       {id: 'e4c9e354-4dc5-45b8-9e7c-e1393b0b1a20', type: 'Scope'} // AuditLog.Read.All
     ]
    }
  ]
  appRoles: [
    {
      allowedMemberTypes: [
        'Application'
      ]
        description: 'Allows the app to read user profiles without a signed in user.'
        displayName: 'Read all users\' full profiles'
        id: '7ab1d382-f21e-4acd-a863-ba3e13f7da61'
        isEnabled: true
        value: 'Directory.Read.All'
    }
  ]
}

resource applicationRegistrationServicePrincipal 'Microsoft.Graph/servicePrincipals@v1.0' = {
  appId: applicationRegistration.appId
}

resource grants 'Microsoft.Graph/oauth2PermissionGrants@v1.0' = {
  clientId: applicationRegistrationServicePrincipal.id
  consentType: 'AllPrincipals'
  resourceId: microsoftGraphServicePrincipal.id
  scope: 'openid offline_access AuditLog.Read.All'
}