Which permissions should you preconsent for your app using Microsoft Graph Toolkit

Which permissions should you preconsent for your app using Microsoft Graph Toolkit

Recently, I wrote about how preconsenting permissions, can help you improve the user experience of your app using Microsoft Graph Toolkit. But how would you know which permissions actually to preconsent? Here is how.

Microsoft Graph Toolkit - the easiest way to connect to Microsoft 365

Using Microsoft Graph Toolkit is the easiest way to connect your app to Microsoft 365. The toolkit helps you implement authentication, retrieves the data from Microsoft Graph, and shows it in your app for you. All you need to focus on is to build your app and add value to your users.

Microsoft Graph Toolkit components know which permissions, also known as scopes, to Microsoft Graph they need, to retrieve the data. If necessary, components automatically prompt the user for granting the missing permissions. While it alleviates you from worrying about auth, it can lead to a poor user experience where the user will get multiple consent prompts in a row granting your app the necessary permissions.

Additional consent prompts displayed by the app when loading upcoming events using Microsoft Graph Toolkit components

In my recent article, I wrote about this behavior in more detail. I also shared a tip, how you can avoid multiple consent prompts. To recap, you need to extend your authentication provider definition with the scopes attribute and list the scopes necessary for your application:

  <script src="https://unpkg.com/@microsoft/mgt/dist/bundle/mgt-loader.js"></script>
  <mgt-msal2-provider client-id="c35a6a0b-7275-4265-a267-d33757115fdc" scopes="user.read, user.readbasic.all, people.read, presence.read.all, presence.read, calendars.read, user.read.all, contacts.read, sites.read.all, mail.readbasic, people.read.all"></mgt-msal2-provider>

But how would you know which permissions are necessary for your app?

How to find out the permissions required for your app

There are a few ways in which you can find out the necessary Microsoft Graph permissions required for your app using Microsoft Graph Toolkit. For completeness, I'll include all of them including the consideration you should take into account.

Get requested permissions from the consent UI

One way you could go about finding out the necessary permissions for your app is to add the toolkit components to your app, going through the separate consents, and scrapping the scopes to include from the UI of the Azure AD login page.

Each time you're prompted to consent permissions, you see a list of scopes.

Azure Active Directory app consent to access user profile

On each consent screen, you'd take note of the requested permissions, figure out their scope name (eg. User.Read), and create a list of unique scopes required for your app. This is hardly convenient. Luckily, there are other ways.

Get permission used by each component

Recently, Microsoft Graph Toolkit extended components with a new static getter named requiredScopes. This getter, returns all scopes required by the particular component. For example, for the Agenda component, the requiredScopes getter returns the calendars.read scope as well as the scopes required by the People component that it uses internally:

export class MgtAgenda extends MgtTemplatedComponent {
  public static get requiredScopes(): string[] {
    return [...new Set(['calendars.read', ...MgtPeople.requiredScopes])];

  // ...

When instantiating your authentication provider, you'd get scopes from all unique components that you use in your app and pass them to the authentication provider:

const scopes = [...new Set(...MgtLogin.requiredScopes, ...MgtAgenda.requiredScopes)];
Providers.globalProvider.scopes = scopes;

Using the requiredScopes getter is more convenient than manually compiling a list of scopes from consent dialogs. Using requiredScopes comes with a caveat though. requiredScopes returns all scopes required by the particular component. It doesn't take into account the configuration of the specific instance of the component. So when using this approach, there are cases where you could end up requesting more permissions than you need.

Use the docs to determine which permissions you need

Last week we've updated the docs for Microsoft Graph Toolkit components. For each component, we've updated the Permissions section to list the different configuration options for each component and the required permissions. For example, have a look at the People component's permissions.

Screenshot of the documentation of permissions for the People component from Microsoft Graph Toolkit

There are multiple ways in which you can configure the People component to show people. You can set it up to show a list of members of the particular group, you can specify the list of user IDs or you can pass a people query. Each of these options requires different permissions. If you'll want to show the presence of the displayed people, you'll need extra permission. By comparing your configuration to the docs, you can easily see which permissions your app needs to preconsent to avoid multiple consent prompts.

I'd say, that as of writing this article, this is the easiest and the most reliable way to get the list of the necessary permissions to preconsent for your app.

Future idea: get effective scopes

Thinking about how we could help you determine the necessary permissions for your app, I thought of the following solution. What if each component would return the list of the scopes it effectively needs, based on its current configuration. You could then get all instances of Microsoft Graph Toolkit components on the page, or maybe the authentication provider could do it for you, calculate the necessary permissions and pass them to the authentication provider. How does that sound? Would it be helpful? We'd love to hear from you what you think and if there is something else we should take into account.

Over to you

Do you use Microsoft Graph Toolkit? How do you like the way it handles auth? How could we improve it?


comments powered by Disqus