# Microsoft 365: connecting mailboxes

For the assistant to read mail in Microsoft 365 and write drafts there, it
needs access through Microsoft Graph. There are two routes, and both rest on
**an app that the organisation registers in its own Microsoft Entra ID**.
draften has no shared app you would simply consent to. This holds for our
service and for an installation on your own server alike.

## Which route to choose

| | For the whole organisation | With the mailbox account |
|---|---|---|
| In draften | a registration in Organisation → **Integrations** | the **Connect Outlook** button at the mailbox |
| Permissions in Entra | application (Application) | delegated (Delegated) |
| Who has to sign in | nobody | the owner of each mailbox, once |
| Which mailboxes it reaches | every mailbox of the directory (can be narrowed) | only the mailbox whose account signed in |
| Shared mailboxes (info@, sales@) | yes | no — a shared mailbox has no sign-in of its own |
| When someone leaves the company | nothing changes | once their account is blocked, the mailbox disconnects |
| Signing in to draften with a Microsoft account | no, that is a separate matter | the same registration serves sign-in too |

For an organisation with several mailboxes, the **route for the whole
organisation** is simpler: an administrator sets it up once and the mailbox
owners do nothing. **With the mailbox account** suits you when you do not want
to give the app access to every mailbox of the directory, or when you are
introducing signing in with Microsoft accounts anyway.

You can have both routes at once; each mailbox uses one of them.

!> **Never give the app the `Mail.Send` permission.** draften sends nothing,
and without that permission it cannot — which is the point.

## Route A: for the whole organisation

You need an account with the **Global Administrator** or **Privileged Role
Administrator** role — only such an account can consent to Microsoft Graph
application permissions. The registration itself can also be created by an
Application Administrator.

### In Microsoft Entra

1. Open https://entra.microsoft.com → **Identity** → **Applications** →
   **App registrations** → **New registration**.
2. Fill in a name, say `draften – mail`, choose **Accounts in this
   organizational directory only**, **leave the Redirect URI empty** and click
   **Register**.
3. On the **Overview** page, note down the **Application (client) ID** and the
   **Directory (tenant) ID**.
4. **Certificates & secrets** → **Client secrets** → **New client secret**:
   a description (say `draften`) and an expiry of 24 months at most. After
   saving, copy the **Value** column straight away — it is shown only now.
   draften does not need the **Secret ID**. Note down the expiry date too.
5. **API permissions** → **Add a permission** → **Microsoft Graph** →
   **Application permissions**. Tick `Mail.ReadWrite`
   and `MailboxSettings.ReadWrite` and click **Add permissions**.
   `MailboxSettings.ReadWrite` serves only the colour of the Outlook category;
   without it the category is added without a colour. Optionally add
   `User.Read.All` — with it draften checks the mailbox's aliases; without it
   the connection test says it cannot check them.
6. Click **Grant admin consent for …** and confirm. Every row must have a
   green tick.

### In draften

1. Open Organisation → **Integrations**, the **Organisation-wide mail access**
   card. Registrations are managed by the organisation's owner or managers.
2. **System**: **Microsoft 365 (Entra)**. Fill in **Name**, **Directory
   (tenant) ID**, **Application (client) ID**, **Client secret** (the value
   from step 4, not its ID) and **Secret expires**. Click **Add
   registration**. The secret is stored encrypted and never shown again.
3. The registration connects nothing by itself. On each mailbox's page, in the
   **Mail access** card, choose this registration under **Use**, click
   **Apply** and then **Test the connection**. Only someone who owns the
   mailbox and is also the owner or a manager of the organisation sees the
   choice (the organisation's owner owns every mailbox). The whole procedure
   with screenshots is in the guide [Adding and connecting a
   mailbox](/en/admin/adding-a-mailbox).

With **Mailbox automatically** on ([How members sign
in](/en/admin/member-sign-in)), a new mailbox is bound to the registration by
itself when exactly one is active for Microsoft 365.

### Narrowing to selected mailboxes (optional)

An application permission reaches every mailbox of the directory; draften is
the guard (a member cannot add a mailbox, the assistant neither sends nor
deletes anything). Whoever wants a technical fence as well narrows the app to
a security group with an `ApplicationAccessPolicy` in Exchange Online
(PowerShell with the ExchangeOnlineManagement module):

```
Connect-ExchangeOnline -UserPrincipalName admin@<tenant>.onmicrosoft.com
New-DistributionGroup -Name "draften - allowed mailboxes" -Alias draften-mailboxes -Type Security -Members mailbox@firma.cz
New-ApplicationAccessPolicy -AppId <Application (client) ID> -PolicyScopeGroupId draften-mailboxes@firma.cz -AccessRight RestrictAccess -Description "draften: allowed mailboxes only"
Test-ApplicationAccessPolicy -Identity mailbox@firma.cz -AppId <Application (client) ID>
```

Then add every further mailbox to the group too, or its connection test fails
with error 403 (`AppOnly AccessPolicy`). The policy usually takes effect
within an hour; we have seen four hours too. As a newer alternative, Microsoft
offers **RBAC for Applications** in Exchange Online; we do not describe it
yet.

### Replacing the secret

The secret has a limited validity, and draften sends no warning before it
ends — the date in the card turns yellow 30 days before expiry and red after
it. Put a reminder in your calendar. Before it expires:

1. In Entra, create a new client secret at the registration (step 4 above).
2. In draften, choose **New secret** at the registration and enter the new
   value and the new date.
3. Delete the old secret in Entra.

If the secret expires first, the mailboxes disconnect (`invalid_client`) and
the assistants skip them. After replacing the secret, run **Test the
connection** on the mailboxes — a successful test switches the mailbox back
on.

## Route B: with the mailbox account (Connect Outlook)

This registration has **delegated** permissions: the app may do only what the
signed-in person may, and only in their own mailbox. The same registration
also serves **signing in to draften with a Microsoft account**. Keep it
separate from the registration for route A.

### In Microsoft Entra

1. In draften, first open Organisation → **How members sign in**, the
   **Account sign-in and mailbox connections** card. It shows two **redirect
   URIs** made exactly for your draften address — ending in `/auth/callback`
   and `/mailboxes/connect/callback`. Copy them from there; they must match
   character for character.
2. In https://entra.microsoft.com → **App registrations** → **New
   registration**: a name, say `draften – sign-in`, **Accounts in this
   organizational directory only**, **Redirect URI**: the **Web** platform
   and the first address from the card. Click **Register**.
3. **Authentication** → at the Web platform, **Add URI** → the second address
   from the card → **Save**.
4. On **Overview**, note down the **Application (client) ID** and the
   **Directory (tenant) ID**.
5. **Certificates & secrets** → **New client secret** → copy the **Value**
   and note down the expiry date.
6. **API permissions** → **Add a permission** → **Microsoft Graph** →
   **Delegated permissions**: `openid`, `profile`, `email`, `offline_access`,
   `User.Read`, `Mail.ReadWrite` and `MailboxSettings.ReadWrite`.
   Without `offline_access` the connection does not last — draften would get
   no refresh token.
7. Click **Grant admin consent for …**. If your organisation does not let
   users consent to apps, connecting would otherwise end with a message that
   the consent was refused.

### In draften

1. The **organisation owner** fills in the **Application (client) ID** and
   the **Client secret** under **Entra registration for Sign in with
   Microsoft and Connect Outlook** in the **Account sign-in and mailbox
   connections** card and clicks **Save**.
2. The **mailbox owner** opens the mailbox's page and clicks **Connect
   Outlook** in the **Mail access** card. They sign in **with that mailbox's
   account** — draften refuses any other — and allow the access. Only the
   mailbox owner sees the button, and only when the organisation has the
   registration.
3. Then **Test the connection**.

You switch on **signing in with a Microsoft account** on the same page: put
the Directory (tenant) ID into **Microsoft directory (Entra) ID**. Once the
organisation has both the registration and the directory ID, members sign in
with their Microsoft accounts and their passwords stop working — see [How
members sign in](/en/admin/member-sign-in).

### When a mailbox disconnects

- **The registration's secret expired** — create a new one in Entra, save it
  in the Account sign-in and mailbox connections card and click **Reconnect
  Outlook** on the mailboxes.
- **The person left or their account was blocked** — Microsoft stops issuing
  tokens and draften disconnects the mailbox. Connect a mailbox without a
  sign-in of its own through route A.
- **"The provider issued no refresh token"** — the registration lacks the
  `offline_access` permission (step 6).
- **"A different account signed in than the mailbox address"** — when
  connecting, sign in with the account of exactly that mailbox; whoever has
  several Microsoft accounts in the browser picks the right one.

## Connection test errors

The test checks three steps: **Access**, **Token and permission** and
**Reading the Inbox**. Each gets a tick, or a cross with the reason:

| In the message | What it means | What to do |
|---|---|---|
| `AADSTS7000215`, `AADSTS7000222`, `invalid_client` | a wrong or expired client secret | create a new secret and save it in draften |
| `AADSTS700016`, `AADSTS90002`, `unauthorized_client` | a wrong Application ID or Directory ID | copy both IDs again from Overview |
| `AADSTS65001`, `AADSTS650057`, `consent_required` | admin consent is missing | **Grant admin consent** at the registration |
| a token without `Mail.ReadWrite` | the permission is missing or not consented to | add the permission and grant consent |
| `invalid_grant`, `AADSTS50173`, `AADSTS700082`, `AADSTS70008` | the account connection expired or was revoked | **Reconnect Outlook** |
| HTTP 403 `AppOnly AccessPolicy` | the mailbox is not in the access policy's group | add it to the group and wait |
| HTTP 404 | no such mailbox exists | check the address; the mailbox must have Exchange Online |
| HTTP 401 | another directory, or a missing permission | check the Directory ID and the permissions |

Other errors are covered in [Troubleshooting](/en/admin/troubleshooting).
