> For the complete documentation index, see [llms.txt](https://docs.elimity.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.elimity.com/exchange-online/step-by-step-deployment-guide.md).

# Step-by-step deployment guide

The Exchange Online connector imports mailboxes and the permissions people hold on them, so you can review who can read, send as, or act on behalf of whom.

### What This Connector Imports

| Entity         | What it is                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------- |
| **Mailbox**    | Every mailbox in the organisation, with its alias, user principal name and recipient type               |
| **Permission** | One per mailbox and access right, named `Mailbox - AccessRight`                                         |
| **User**       | Every recipient in the organisation, plus the principals that hold permissions without being recipients |

### Authentication Method

The connector authenticates as an application, not as a user. You register an application in Microsoft Entra ID, give it permission to manage Exchange Online, and assign it a role that decides which data it may read.

No mailbox contents are ever read, only who has access to what.

### Step 1: Register an Application in Microsoft Entra ID

1. In the Entra admin centre, go to **Identity → Applications → App registrations**.
2. Select **New registration**.
3. Give it a name, for example `Elimity Exchange Online`.
4. Leave the redirect URI empty (this application never signs a user in)
5. Select **Register**.

Note the **Application (client) ID** and **Directory (tenant) ID** from the overview page. You will need both.

### Step 2: Create a Client Secret

1. Open your new application and go to **Certificates & secrets**.
2. Under **Client secrets**, select **New client secret**.
3. Give it a description and an expiry.
4. Select **Add**, then copy the **Value** immediately.

The secret value is shown only once. If you navigate away before copying it, create a new one.

Note the expiry date. When the secret expires the import will start failing to authenticate, and it needs replacing in the source configuration.

### Step 3: Grant the Exchange Online API Permission

1. In your application, go to **API permissions**.
2. Select **Add a permission → APIs my organization uses**.
3. Search for **Office 365 Exchange Online** and select it.
4. Choose **Application permissions**, then select **Exchange.ManageAsApp**.
5. Select **Add permissions**.
6. Select **Grant admin consent** and confirm.

### Step 4: Assign a Role to the Application

The API permission from Step 3 lets the application reach Exchange. A **role** decides what it may read.

In **Entra ID → Roles and administrators**, assign **Global Reader** to the application you registered in Step 1.

Global Reader is read-only across Microsoft 365 and covers everything this connector needs: listing mailboxes and recipients, reading mailbox and *Send As* permissions, and reading RBAC role groups.

The connector only reads. It never creates, changes or deletes anything in Exchange, so a role with write access is never required.

#### If a narrower role is required

Some organisations prefer to grant less than Global Reader. The application must at minimum be able to run `Get-EXOMailbox`, `Get-EXORecipient`, `Get-EXOMailboxPermission` and `Get-EXORecipientPermission`, or the import cannot start.

`Get-RoleGroup` is optional. Without it the import completes normally, but permissions granted through an RBAC role group are not imported - they are listed as skipped trustees in an alert.

### Step 5: Configure the Source in Elimity

Create a custom source and set **SDK version** to **2**.

| Field          | Required | Description                                                                                     |
| -------------- | -------- | ----------------------------------------------------------------------------------------------- |
| `tenantId`     | Yes      | Directory (tenant) ID from Step 1                                                               |
| `clientId`     | Yes      | Application (client) ID from Step 1                                                             |
| `clientSecret` | Yes      | Secret value from Step 2                                                                        |
| `parallel`     | No       | How many branches run side by side. `false` (default) is one, `true` is eight, or give a number |

**SDK version must be 2.** With version 1 the connector cannot split the import and will run until it times out.

{% file src="/files/wK94L1Dhq2l51ZPvNRq3" %}

#### Choosing a value for `parallel`

Left unset, the import runs sequentially. That is the safest first run but the slowest, and on a large environment it can take many hours.&#x20;

### Troubleshooting

#### An alert mentions `Get-RoleGroup` is not recognized

The application's role does not allow reading role groups. The import completes without them. See Step 4 if you want those permissions included.

#### The import fails to authenticate

Usually an expired client secret. Create a new one (Step 2) and update the source configuration.

#### The import times out

Check that **SDK version** is set to **2** on the source. With version 1 the import runs as a single request and will time out on a large environment.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.elimity.com/exchange-online/step-by-step-deployment-guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
