Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

appRoleAssignedTo fails when deployed by application in DevOps pipeline #125

Closed
Agazoth opened this issue May 27, 2024 · 6 comments
Closed
Assignees
Labels
bug Something isn't working triaged Team has triaged the item

Comments

@Agazoth
Copy link

Agazoth commented May 27, 2024

Bicep version
0.27.1

Resource and API version
Microsoft.Graph/[email protected]

Auth flow
Automated - Azure DevOps pipeline

Deployment details
{"error":{"code":"BadRequest","target":"/resources/appRoleAssignedTo[1]","message":"Unsupported token. Unable to initialize the authorization context. Graph client request id: a294e9fc-7bd2-45fa-badc-c8f33c8b4250. Graph request timestamp: Mon, 27 May 2024 14:58:35 GMT."}} (Code:DeploymentOperationFailed) Status Message: {"error":{"code":"BadRequest","target":"/resources/appRoleAssignedTo[0]","message":"Unsupported token. Unable to initialize the authorization context. Graph client request id: e2a79716-fc70-4f3c-856c-f071586fa797. Graph request timestamp: Mon, 27 May 2024 14:58:35 GMT."}} (Code:DeploymentOperationFailed) CorrelationId: a05e1c13-c5aa-4c04-b2c6-4a5ee8aedf6c

Describe the bug
The deployment runs as expected without the appRoleAssignedTo resource.

The deployment runs as expected with the appRoleAssignedTo resource when run from an interactive PowerShell console with a user having GA access

To Reproduce
main.bicep

provider microsoftGraph

param resourceGroupName string = 'rg-myapp-graphtest'
param location string = 'westeurope'
param groupPrefix string = 'gt'
param environment string = 'd'
param webApiName string = 'MyAppWebApi'
param webAppName string = 'MyAppWebApp'
param uniqueName string = 't3st6raph'

targetScope = 'subscription'

resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: resourceGroupName
  location: location
}

var appRoles = [
  {
    id: guid('a7eaacc4-21ff-4398-8f06-c84fc4b18666')
    value: 'MyApp.SuperUser'
    displayName: 'SuperUser'
    description: 'Grants SuperUser access to MyApp'
    allowedMemberTypes: ['User']
  }
  {
    id: guid('a7eaacc3-21ff-4398-8f06-c84fc4b18666')
    value: 'MyApp.User'
    displayName: 'User'
    description: 'Grants User access to MyApp'
    allowedMemberTypes: ['User']
  }
]

// Create roles
resource groups 'Microsoft.Graph/[email protected]' = [
  for (item, index) in appRoles: {
    displayName: '${groupPrefix}-${item.displayName}-${environment}'
    mailEnabled: false
    mailNickname: '${groupPrefix}${item.displayName}${environment}'
    uniqueName: '${groupPrefix}${item.displayName}${environment}'
    description: '${item.displayName} access to MyApp ${environment} application'
    securityEnabled: true
    owners: [
      apiSpn.id
    ]
  }
]

resource appRoleAssignedTo 'Microsoft.Graph/[email protected]' = [
  for (item, index) in appRoles: {
    principalId: groups[index].id
    resourceId: appSpn.id
    appRoleId: appRoles[index].id
  }
]

// Create spns and apps
resource apiSpn 'Microsoft.Graph/[email protected]' = {
  displayName: '${webApiName}-${environment}'
  servicePrincipalType: 'Application'
  appId: apiApp.appId
  accountEnabled: true
}

resource apiApp 'Microsoft.Graph/[email protected]' = {
  displayName: '${webApiName}-${environment}'
  uniqueName: '${webApiName}-${environment}'
  signInAudience: 'AzureADMyOrg'
  api: {
    oauth2PermissionScopes: [
      {
        adminConsentDescription: 'Access MyApp as user'
        adminConsentDisplayName: 'Access MyApp as user'
        id: guid('a7eaacc9-ba31-4d61-89e7-88639da4a666') // "Random" guid
        isEnabled: true
        type: 'Admin'
        userConsentDescription: 'Access MyApp as user'
        userConsentDisplayName: 'Access MyApp as user'
        value: 'access_as_user'
      }
    ]
  }
  requiredResourceAccess: [
    {
      resourceAppId: '00000003-0000-0000-c000-000000000000'
      resourceAccess: [
        {
          id: 'e1fe6dd8-ba31-4d61-89e7-88639da4683d' // User.Read
          type: 'Scope' // The type of the permission (Scope or Role)
        }
      ]
    }
  ]
}

// Frontend app and spn

resource appSpn 'Microsoft.Graph/[email protected]' = {
  displayName: '${webAppName}-${environment}'
  servicePrincipalType: 'Application'
  appId: appApp.appId
  accountEnabled: true
}

resource appApp 'Microsoft.Graph/[email protected]' = {
  displayName: '${webAppName}-${environment}'
  uniqueName: '${webAppName}-${environment}'
  signInAudience: 'AzureADMyOrg'
  spa: {
    redirectUris: [
      'https://app-${uniqueName}-webapi.azurewebsites.net'
    ]
  }
  appRoles: appRoles
  requiredResourceAccess: [
    {
      resourceAppId: apiApp.appId
      resourceAccess: [
        {
          id: apiApp.api.oauth2PermissionScopes[0].id //'a7eaacc9-ba31-4d61-89e7-88639da4a666' // access_as_user
          type: 'Scope' // The type of the permission
        }
      ]
    }
    {
      resourceAppId: '00000003-0000-0000-c000-000000000000'
      resourceAccess: [
        {
          id: 'e1fe6dd8-ba31-4d61-89e7-88639da4683d' // User.Read
          type: 'Scope' // The type of the permission
        }
      ]
    }
  ]
}

module addPreAuthApps 'modules/AddPreauthenticationToApplication.bicep' = {
  name: 'addPreauth'
  scope: resourceGroup
  params: {
    appId: appApp.appId
    parentAppUniqueName: apiApp.uniqueName
    delegatedPermissionIds: [
      apiApp.api.oauth2PermissionScopes[0].id
    ]
  }
}

module/AddPreauthenticationToApplication.bicep (preauthentication can only be done after app creation)

provider microsoftGraph

param parentAppUniqueName string
param appId string
param delegatedPermissionIds array

resource parentApp 'Microsoft.Graph/[email protected]' existing = {
  uniqueName: parentAppUniqueName
}

resource preAuth 'Microsoft.Graph/[email protected]' = {
  displayName: parentApp.displayName
  uniqueName: parentApp.uniqueName
  identifierUris: [
    'api://${parentApp.appId}'
  ]
  api: {
    preAuthorizedApplications: [
      {
        appId: appId
        delegatedPermissionIds: delegatedPermissionIds
      }
    ]
  }
}

Additional context
The service principal running the pipeline is owner on the subscription and have these permissions:
image

These access rights are in accordance with the highest privileges in the documentation found here: https://learn.microsoft.com/en-us/graph/templates/reference/overview?view=graph-bicep-1.0

@Agazoth Agazoth added the bug Something isn't working label May 27, 2024
@dkershaw10
Copy link
Collaborator

@eketo-msft Please investigate this issue.

@dkershaw10 dkershaw10 added the triaged Team has triaged the item label May 28, 2024
@Agazoth
Copy link
Author

Agazoth commented Jun 2, 2024

@dkershaw10 or @eketo-msft were you able to reproduce the issue? I still have it.

@eketo-msft
Copy link
Contributor

Hey @Agazoth, the issued has been narrowed down to a downstream microservice. We are working with their engineering team to mitigate this issue and I hope to have an ETA today or tomorrow. Thank you for your patience.

@eketo-msft
Copy link
Contributor

Hey @Agazoth, we are on track to resolve this issue early next week after the downstream microservice completes their deployment work. I'll let you know here when the issue is resolved so you can test again.

@eketo-msft
Copy link
Contributor

Hey @Agazoth, downstream dependencies are updated, and testing looks good. Can you please retry your deployment and let me know if everything is working now? Thanks!

@Agazoth
Copy link
Author

Agazoth commented Jun 12, 2024

Hey @eketo-msft, yes, it works now. Thanks!

@Agazoth Agazoth closed this as completed Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triaged Team has triaged the item
Projects
None yet
Development

No branches or pull requests

3 participants