Microsoft 365

Setup

Connecting to Microsoft 365 data requires:

  1. creating one Microsoft Entra ID (former Azure Active Directory, AAD) application per Microsoft 365 data source (eg, msft-entra-id, outlook-mail, outlook-cal, etc).

  2. configuring an authentication mechanism to permit each proxy instance to authenticate with the Microsoft Graph API. (since Sept 2022, the supported approach is federated identity credentials)

  3. granting admin consent to each Entra ID enterprise application to specific scopes of Microsoft 365 data the connection requires.

Steps (1) and (2) are handled by the terraform examples. To perform them, the machine running terraform must be authenticated with Azure CLI as a Microsoft Entra ID user with, at minimum, the following role in your Microsoft 365 tenant:

Please note that this role is the least-privileged role sufficient for this task (creating a Microsoft Entra ID Application), per Microsoft's documentation. See Least privileged roles by task in Microsoft Entra ID.

This role is needed ONLY for the initial terraform apply . After each Azure AD enterprise application is created, the user will be set as the owner of that application, providing ongoing access to read and update the application's settings. At that point, the general role can be removed.

Step (3) is performed via the Microsoft Entra ID web console through an user with administrator permissions. Running the terraform examples for steps (1)/(2) will generate a document with specific instructions for this administrator. This administrator must have, at minimum, the following role in your Microsoft 365 tenant:

Again, this is the least-privileged role sufficient for this task, per Microsoft's documentation. See Least privileged roles by task in Microsoft Entra ID.

Security

Authentication

Psoxy uses Federated Identity Credentials to authenticate with the Microsoft Graph API. This approach avoids the need for any secrets to be exchanged between your Psoxy instances and your Microsoft 365 tenant. Rather, each API request from the proxy to Microsoft Graph API is signed by an identity credential generated in your host cloud platform. You configure your Azure AD application for each connection to trust this identity credential as identifying the application, and Microsoft trusts your host cloud platform (AWS/GCP) as an external identity provider of those credentials.

Neither your proxy instances nor Worklytics ever hold any API key or certificate for your Microsoft 365 tenant.

See Microsoft Workload Identity Federation docs for details. Specifically, the relevant scenario is workload running in either GCP or AWS (your proxy host platform)

Authorization and Scopes

The following Scopes are required for each connector. Note that they are all READ-only scopes.

NOTE: the above scopes are copied from infra/modules/worklytics-connector-specs. They are accurate as of 2023-04-12. Please refer to that module for a definitive list.

NOTE: that Mail.ReadBasic affords only access to email metadata, not content/attachments.

NOTE: These are all 'Application' scopes, allowing the proxy itself data access as an application, rather than on behalf of a specific authenticated end-user ('Delegated' scopes).

Online Meetings support (Only for Teams connector)

Besides of having OnlineMeetings.Read.All and OnlineMeetingArtifact.Read.All scope defined in the application, you need to allow a new role and a policy on the application created for reading OnlineMeetings. You will need Powershell for this.

Please follow the steps below:

  1. Ensure the user you are going to use for running the commands has the "Teams Administrator" role. You can add the role in the Microsoft 365 Admin Center

NOTE: It can be assigned through Entra Id portal in Azure portal OR in Entra Admin center https://admin.microsoft.com/AdminPortal/Home. It is possible that even login with an admin account in Entra Admin Center the Teams role is not available to assign to any user; if so, please do it through Azure Portal (Entra Id -> Users -> Assign roles)

  1. Install PowerShell Teams module.

  2. Run the following commands in Powershell terminal:

Connect-MicrosoftTeams

And use the user with the "Teams Administrator" for login it.

  • Add a policy for the application created for the connector, providing its application id

  • Grant the policy to the whole tenant (NOT to any specific application or user)

Issues:

  • If you receive "access denied" is because no admin role for Teams has been detected. Please close and reopen the Powershell terminal after assigning the role.

  • Commands have been tested over a Powershell (7.4.0) terminal in Windows, installed from Microsoft Store and with Teams Module (5.8.0). It might not work on a different environment

Troubleshooting

Lack of 'Cloud Application Administrator' role

If you do not have the 'Cloud Application Administrator' role, someone with that or an alternative role that can create Azure AD applications can create one application per connection and set you as an owner of each.

You can then import these into your Terraform configuration.

First, try terraform plan | grep 'azuread_application' to get the Terraform addresses for each application that your configuration will create.

Second, ask your Microsoft admin to create an application for each of those, set you as the owner, and send you the Object ID for each.

Third, use terraform import <address> <object-id> to import each application into your Terraform state.

At that point, you can run terraform apply and it should be able to update the applications with the settings necessary for the proxy to connect to Microsoft Graph API. After that apply, you will still need a Microsoft 365 admin to perform the admin consent step for each application.

See https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application#import for details.

Certificate creation via Terraform DEPRECATED

DEPRECATED - will be removed in v0.5; this is not recommended approach, for a variety of reasons, since Microsoft released support for federated credentials in ~Sept 2022. See our module azuread-federated-credentials for preferred alternative.

Psoxy's terraform modules create certificates on your machine, and deploy these to Azure and the keys to your AWS/GCP host environment. This all works via APIs.

Sometimes Azure is a bit finicky about certificate validity dates, and you get an error message like this:

│ Error: Adding certificate for application with object ID "350c0b06-10d4-4908-8708-d5e549544bd0"

│   with module.msft-connection-auth["azure-ad"].azuread_application_certificate.certificate,
│   on ../../modules/azuread-local-cert/main.tf line 27, in resource "azuread_application_certificate" "certificate":
│   27: resource "azuread_application_certificate" "certificate" {

│ ApplicationsClient.BaseClient.Patch(): unexpected status 400 with OData
│ error: KeyCredentialsInvalidEndDate: Key credential end date is invalid.

Just running terraform apply again (and maybe again) usually fixes it. Likely it's something with with Azure's clock relative to your machine, plus whatever flight time is required between cert generation and it being PUT to Azure.

Last updated