Microsoft OAuth uses PKCE flow (Proof Key for Code Exchange) with a public client. No client secret is required for desktop applications.
Overview
Craft Agents integrates with Microsoft 365 services using Azure AD OAuth 2.0. Supports both personal Microsoft accounts and work/school accounts (Azure AD) through the “common” tenant endpoint. Supported Services:- Outlook: Email, contacts, calendar events
- OneDrive: File storage and sharing
- Microsoft Calendar: Event management
- Teams: Chat, channels, messages
- SharePoint: Site and document access
Prerequisites
- A Microsoft account (personal or work/school)
- Access to Azure Portal
- 10 minutes for initial setup
Complete Setup Guide
Create Azure App Registration
- Go to Azure Portal
- Search for Azure Active Directory (or Microsoft Entra ID)
- Click App registrations in left sidebar
- Click New registration
- Name: e.g., “Craft Agent Desktop”
- Supported account types:
- Choose Accounts in any organizational directory and personal Microsoft accounts
- This supports both work/school and personal accounts
- Redirect URI: Leave blank (add in next step)
- Click Register
- Note your Application (client) ID — you’ll need this
Add Mobile and Desktop Platform
- In your app registration, click Authentication in left sidebar
- Click Add a platform
- Select Mobile and desktop applications
- Check https://login.microsoftonline.com/common/oauth2/nativeclient
- Add custom redirect URI:
http://localhost/callback- This allows the OAuth callback to work on any local port
- Click Configure
PKCE flow is automatically used for mobile and desktop applications. No client secret is needed.
Configure API Permissions
- Click API permissions in left sidebar
- Click Add a permission
- Select Microsoft Graph
- Choose Delegated permissions (not Application permissions)
Outlook Permissions
Outlook Permissions
Mail.ReadWrite- Read and write emailMail.Send- Send emailUser.Read- Sign in and read user profile
Calendar Permissions
Calendar Permissions
Calendars.ReadWrite- Manage calendar eventsUser.Read- Sign in and read user profile
OneDrive Permissions
OneDrive Permissions
Files.ReadWrite- Read and write filesUser.Read- Sign in and read user profile
Teams Permissions
Teams Permissions
Chat.ReadWrite- Read and send chat messagesChannelMessage.Send- Send messages to channelsUser.Read- Sign in and read user profile
SharePoint Permissions
SharePoint Permissions
- Click Add permissions
- Permissions are granted on first user login (no admin consent needed for delegated permissions)
offline_access is automatically included by Craft Agent to request refresh tokens.OAuth Flow
Browser Opens
- Microsoft login page opens
- Sign in with your Microsoft account
- Choose account (personal or work/school)
Grant Permissions
- Review requested permissions
- Click Accept to authorize
- Browser redirects to callback URL
PKCE Security Flow
Microsoft OAuth uses PKCE (Proof Key for Code Exchange) for enhanced security:- Generate code verifier: Random 32-byte string (base64url encoded)
- Create code challenge: SHA-256 hash of verifier (base64url encoded)
- Authorization request: Send challenge to Microsoft
- Token exchange: Send verifier to prove you initiated the request
PKCE eliminates the need for a client secret, making it ideal for desktop and mobile apps where secrets can’t be securely stored.
Scopes by Service
Outlook Scopes
Outlook Scopes
Calendar Scopes
Calendar Scopes
OneDrive Scopes
OneDrive Scopes
Teams Scopes
Teams Scopes
SharePoint Scopes
SharePoint Scopes
offline_access is required to receive a refresh token for long-term access.Token Refresh
Microsoft access tokens expire after 1 hour. Craft Agent automatically refreshes them:- Access token lifespan: 1 hour
- Refresh token lifespan: 90 days (rolling)
- Automatic refresh: Before each API call if token expired
- Token rotation: Microsoft may issue new refresh tokens
Multi-Tenant Support
Craft Agent uses the common tenant endpoint:- Personal Microsoft accounts (Outlook.com, Hotmail, Live)
- Work/school accounts (Azure AD, Microsoft 365)
- Multi-tenant Azure AD apps
For single-tenant (organization-only) apps, replace
common with your tenant ID in Azure app configuration.Source Configuration
Exampleconfig.json for a Microsoft source:
Outlook
OneDrive
Teams
Security Best Practices
- Encrypted storage: Tokens stored in
~/.craft-agent/credentials.enc(AES-256-GCM) - PKCE flow: No static client secret to compromise
- CSRF protection: State parameter prevents cross-site attacks
- Scope minimization: Only request permissions you need
- Token expiration: Access tokens expire after 1 hour
- Refresh token rotation: Microsoft may rotate refresh tokens for security
Troubleshooting
Error: Microsoft OAuth not configured
Error: Microsoft OAuth not configured
Client ID is missing:
- Verify
MICROSOFT_OAUTH_CLIENT_IDenvironment variable is set - Rebuild Craft Agents after setting the env var
- Check
.envfile is in the project root
Error: AADSTS50011 - Redirect URI mismatch
Error: AADSTS50011 - Redirect URI mismatch
The redirect URI doesn’t match Azure app configuration:
- Go to Authentication in your Azure app registration
- Ensure Mobile and desktop applications platform is added
- Verify
http://localhost/callbackis listed - Save and try again
Error: OAuth state mismatch
Error: OAuth state mismatch
CSRF protection triggered:
- Check system time is correct
- Clear browser cache
- Close other OAuth flows
- Try again
Error: AADSTS65001 - User consent required
Error: AADSTS65001 - User consent required
User hasn’t consented to permissions:
- This is expected on first login
- Click Accept in the consent dialog
- If blocked by admin, contact your IT department
Token refresh fails
Token refresh fails
Refresh token might be expired or revoked:
- Re-authenticate to get a new refresh token
- Ensure
offline_accessscope is included (automatic) - Check refresh token hasn’t expired (90-day limit)
- Verify app hasn’t been revoked in Microsoft account settings
Error: Failed to get user info from Microsoft Graph
Error: Failed to get user info from Microsoft Graph
Access token doesn’t have
User.Read permission:- Go to API permissions in Azure app registration
- Verify
User.Readis added - Re-authenticate to grant new permissions