Every migration tool that accesses Microsoft 365 data does so through an Azure App Registration. This is a service identity in your Azure Active Directory that holds the credentials and permissions the tool uses. Setting one up incorrectly is the most common reason migrations fail to start.
Why application permissions, not delegated
There are two types of Graph API permissions: delegated (acts as a signed-in user) and application (acts as the app itself). Migrations must use application permissions because:
- Migrations run unattended for hours — delegated tokens expire in 60–90 minutes.
- You need access to every mailbox and drive, not just the admin's own.
- Application permissions can be scoped with admin consent so no user needs to individually consent.
Creating the app registration
- 1Go to portal.azure.com and sign in as a Global Admin.
- 2Navigate to Azure Active Directory → App registrations → New registration.
- 3Name it something identifiable (e.g. "TheMigrator - Source Tenant").
- 4Set Supported account types to "Accounts in this organizational directory only".
- 5Leave the Redirect URI blank for now — we'll add it after. Click Register.
- 6On the overview page, copy the Application (client) ID and Directory (tenant) ID — you'll need both.
Adding a client secret
- 1In the app registration, go to Certificates & secrets → Client secrets → New client secret.
- 2Set a description and choose an expiry (24 months is typical for migration work).
- 3Click Add, then immediately copy the Value — it will never be shown again after you navigate away.
The client secret value is only shown once. If you navigate away before copying it, you must delete and recreate the secret.
Required permissions by workload
Go to API permissions → Add a permission → Microsoft Graph → Application permissions, then add:
- Email: Mail.ReadWrite, Calendars.ReadWrite, Contacts.ReadWrite, User.Read.All, Organization.Read.All
- SharePoint: Sites.FullControl.All, User.Read.All, Organization.Read.All
- OneDrive: Files.ReadWrite.All, User.Read.All, Organization.Read.All
- Teams: TeamSettings.ReadWrite.All, ChannelMessage.Read.All, User.Read.All, Organization.Read.All
Granting admin consent
After adding all required permissions, click "Grant admin consent for [your tenant]". This requires a Global Admin. Without this step, every API call will fail with a 403 Forbidden error.
Create separate app registrations for source and destination tenants. Using the same app registration for both sides creates a security dependency — if the secret rotates on one side, both stop working.