Easily grant API permissions using the Office 365 CLI

Granting API permissions without SharePoint Framework packages just got easier with the Office 365 CLI.

APIs is where insights are

One of the frequent requests, and at the same time challenges, when building SharePoint applications, is to communicate with APIs secured with Azure AD. Whether it's the Microsoft Graph or other enterprise APIs, they allow you to tap into the data and insights within your organization and build solutions that add more value to your organization.

Securely communicate with APIs secured with Azure AD

Authentication isn't trivial, especially when you're just starting, so it was a welcome addition, when Microsoft announced support for connecting to APIs secured with Azure AD as a part of the SharePoint Framework. SharePoint Framework significantly simplifies connecting to APIs secured with Azure AD, taking away concerns like deploying and managing Azure AD applications and securely implementing OAuth flow. Instead, all this is encapsulated inside the SharePoint Framework allowing you to focus on building your solution.

To allow communicating with Azure AD-secured APIs, tenant administrators must grant specific permissions to access these APIs. In the past, the only way to grant these permissions was by issuing a permission request from a SharePoint Framework package for the tenant administrator to review and either approve or reject. Once an API permission has been granted, all solutions and scripts in the tenant can communicate with the approved API.

Inconvenient requesting API permissions

When you think of it, one problem with this approach that arises over time is, that each time you deploy a package, a new API permission request is created for the tenant admin to review. No matter if the permission has been reviewed previously or is already granted. As a result, if you don't manage the API permissions regularly, you will quickly end up with an unmanageable list of permissions.

API permission requests listed in the SharePoint admin center
Who's going to review all these permission requests?

Another challenge is, that while a permission request is issued by a package, once approved, it applies to the whole tenant and the permission is not related to the original package that requested it.

Grant API permissions without SharePoint Framework packages

An alternative approach, that you could consider, could be to grant the specific set of permissions upfront and don't use API permission requests inside SharePoint Framework packages altogether.

The trouble with this in the past was, that there was no standard way of doing this, supported in SharePoint. In one of the previous versions of the Office 365 CLI, we added therefore the support of granting API permissions, by directly manipulating the service principal. It wasn't a trivial approach, but it allowed you to manage your API permissions without having to review ad-hoc permission requests issued from solution packages.

Easily grant API permissions with the Office 365 CLI

Recently, Microsoft released an official way of granting API permissions without using SharePoint Framework packages. The latest version of the Office 365 CLI benefits of this API to let you grant API permission more easily.

To compare, here is how you would grant API permissions to the Microsoft Graph using the original approach that manipulated the service principal:

#!/usr/bin/env bash

# resource to which you want to grant permissions
resource='Microsoft Graph'
# permissions you want to grant
new_scopes='Mail.Read'

echo "Retrieving SharePoint Online Client Extensibility Web Application Principal service principal..."
spid=$(o365 aad sp get -n 'SharePoint Online Client Extensibility Web Application Principal' -o json | jq -r '.objectId')
echo "  $spid"

echo "Retrieving $resource service principal..."
resourceid=$(o365 aad sp get -n "$resource" -o json | jq -r '.objectId')
if [ -z "$resourceid" ]; then
    echo "Service principal $resource not found"
    exit 1
else
    echo "  $resourceid"
fi

echo "Checking if permissions for $resource are already granted..."
grants_raw=$(o365 aad oauth2grant list -i $spid -o json)
scopes=$(echo $grants_raw | jq --arg resourceid $resourceid -r '.[] | select(.resourceId == $resourceid) | {scope} | .[]')

if [ -z "$scopes" ]; then
    echo "No existing permissions found. Setting new permissions..."
    o365 aad oauth2grant add -i $spid -r $resourceid -s "$new_scopes"
    echo "  DONE"
else
    echo "Found permissions: $scopes"
    if [[ "$scopes" = *"$new_scopes"* ]]; then
        echo "Permissions $new_scopes already set"
    else
        grantid=$(echo $grants_raw | jq --arg resourceid $resourceid -r '.[] | select(.resourceId == $resourceid) | {objectId} | .[]')
        echo "Setting new permissions '$scopes $new_scopes'..."
        o365 aad oauth2grant set -i $grantid -s "$scopes $new_scopes"
        echo "  DONE"
    fi
fi

With the recent changes, the same can be done using:

o365 spo serviceprincipal grant add --resource 'Microsoft Graph' --scope 'Mail.Read'

As you can see, the newly released API in SharePoint, simplifies granting permissions a lot. The spo serviceprincipal grant add command is available starting from the v1.10.0 beta version of the Office 365 CLI, which you can install by executing npm install -g @pnp/office365-cli@next.

But there is more to it.

Isolated web parts

In the latest version of the SharePoint Framework (v1.7.0), Microsoft introduced the preview of the isolated web parts capability, which allows you to grant API permissions to a specific solution. Only web parts from this solution are able to obtain an access token with the granted permission. This is enforced by using a separate Azure AD application, dedicated to that solution and the web parts being served in an iframe pointing to a unique domain associated with the unique Azure AD app.

Because isolated permissions apply only to the specific solution, it makes more sense to use SharePoint Framework packages to request them. Still, if you wanted to programmatically manage permissions of this unique Azure AD application, you would need to use the aad commands of the Office 365 CLI that would allow you to retrieve the specific service principal and its permissions.

Summary

Deciding upfront which API permissions you want to grant to scripts in your tenant can save you precious time and improve the security posture of your tenant. Using the Office 365 CLI, you can easily grant these permissions without having to use SharePoint Framework solution packages.

Comments

comments powered by Disqus