Microsoft Entra Setup

This runbook explains how to set up Microsoft Entra app registrations for Outlook email integration and user authentication.

What Gets Created

The setup-outlook.ps1 script creates two app registrations:

1. Email App (Orcha Email - {env})

For email acquisition (reading Outlook inbox):

2. Auth App (Orcha Auth - {env})

For direct user authentication (bypasses Cognito):

Note: Microsoft authentication is handled directly by the application instead of through Cognito because Cognito's OIDC issuer validation rejects Microsoft's multi-tenant tokens (the issuer varies by tenant ID).

When to Run

After deploying Phase 1 (FoundationStack + DataStack) and before deploying Phase 2 (ComputeStack).

Prerequisites

  1. Microsoft account with Azure access (free tier sufficient)
  2. PowerShell with Microsoft.Graph module installed:
    Install-Module Microsoft.Graph -Scope CurrentUser
    
  3. Microsoft Entra tenant ID known (e.g., contoso.onmicrosoft.com)
  4. App domain known (e.g., app.getorcha.com)

Steps

1. Install Microsoft.Graph Module (if needed)

Install-Module Microsoft.Graph -Scope CurrentUser

2. Run the Setup Script

cd /home/volrath/code/orcha/orcha/infra

./scripts/setup-outlook.ps1 `
    -EnvName "prod" `
    -TenantId "contoso.onmicrosoft.com" `
    -AppDomain "app.getorcha.com"

The script will:

3. Add Auth Redirect URI to Email App

The Email App is used for both email acquisition and direct authentication. Add the auth redirect URI to the existing Email App:

Via Azure Portal:

  1. Go to Microsoft Entra admin center
  2. Navigate to Applications > App registrations
  3. Find "Orcha Email - prod" (or your Email App name)
  4. Go to Authentication > Platform configurations > Web
  5. Add redirect URI: https://app.getorcha.com/auth/microsoft/callback
  6. For dev environments, add: https://orcha.barreto.tech/auth/microsoft/callback
  7. Click Save

Via PowerShell:

Connect-MgGraph -Scopes "Application.ReadWrite.All"

$app = Get-MgApplication -Filter "displayName eq 'Orcha Email - prod'"

$currentUris = $app.Web.RedirectUris
$newUris = $currentUris + @(
    "https://app.getorcha.com/auth/microsoft/callback",
    "https://orcha.barreto.tech/auth/microsoft/callback"
)

Update-MgApplication -ApplicationId $app.Id -Web @{
    RedirectUris = $newUris
}

4. Create SSM Parameter for Auth State Secret

Generate a secure secret for HMAC state signing:

# Generate a 32-character random secret
openssl rand -base64 24

# Add to your secrets file
echo "/v1-orcha/microsoft-auth-state-secret=<generated-secret>" >> secrets

# Update SSM
./scripts/update-secrets.sh --from-file secrets

5. Verify Setup

  1. Go to Microsoft Entra admin center

  2. Navigate to Applications > App registrations

  3. Find "Orcha Email - prod" and verify:

Troubleshooting

"You can't sign in here with a personal account"

Cause: App registration doesn't support personal Microsoft accounts.

Fix: The app must be created with:

Delete and recreate the apps with -DeleteExisting:

./scripts/setup-outlook.ps1 `
    -EnvName "prod" `
    -TenantId "contoso.onmicrosoft.com" `
    -AppDomain "app.getorcha.com" `
    -DeleteExisting

"AADSTS50011: The reply URL specified in the request does not match"

Cause: Redirect URI mismatch.

Fix:

  1. Check redirect URI in Entra exactly matches callback URL
  2. For auth: https://app.getorcha.com/auth/microsoft/callback
  3. For email: https://app.getorcha.com/oauth/outlook/callback
  4. Include/exclude trailing slashes consistently
  5. Check for http vs https mismatch

"AADSTS7000215: Invalid client secret"

Cause: Client secret expired or copied incorrectly.

Fix:

  1. Go to app registration > Certificates & secrets
  2. Create new client secret
  3. Update SSM parameter /v1-orcha/outlook-client-secret

401 Unauthorized on Microsoft Graph API

Cause: Missing permissions or wrong token version.

Fix:

  1. Check API permissions include all required: Mail.Read, User.Read, offline_access
  2. Verify manifest has accessTokenAcceptedVersion: 2

Microsoft login state verification fails

Cause: Missing or incorrect state secret.

Fix:

  1. Verify SSM parameter exists: /v1-orcha/microsoft-auth-state-secret
  2. Generate a new secret if needed and update SSM

Reference

Resource Prod Value
Email App Name Orcha Email - prod
App Domain app.getorcha.com
Email Redirect URI https://app.getorcha.com/oauth/outlook/callback
Auth Redirect URI https://app.getorcha.com/auth/microsoft/callback
Local Dev Auth URI https://orcha.barreto.tech/auth/microsoft/callback
Email API Permissions Mail.Read, User.Read, offline_access
Auth API Permissions openid, email, profile
Client Secret Expiry 24 months
Script scripts/setup-outlook.ps1

SSM Parameters

Email Acquisition (Orcha Email - prod):

Parameter Purpose
/v1-orcha/outlook-client-id Microsoft OAuth client ID for email
/v1-orcha/outlook-client-secret Microsoft OAuth client secret for email
/v1-orcha/outlook-state-secret HMAC secret for email OAuth state

Direct Authentication (Orcha Auth - prod):

Parameter Purpose
/v1-orcha/microsoft-auth-client-id Microsoft OAuth client ID for auth
/v1-orcha/microsoft-auth-client-secret Microsoft OAuth client secret for auth
/v1-orcha/microsoft-auth-state-secret HMAC secret for auth OAuth state

Architecture

Email Acquisition:
  User → App → Microsoft → App → Store tokens in SSM

Direct Authentication (bypasses Cognito):
  User → App → Microsoft → App → Validate JWT → Create session

Why not Cognito for Microsoft?
  Cognito's OIDC issuer validation requires an exact match, but Microsoft
  multi-tenant tokens have tenant-specific issuers like:
  - https://login.microsoftonline.com/{tenant-id}/v2.0

  The issuer varies by user's organization, so Cognito rejects the tokens.
  Direct authentication validates the issuer pattern instead of exact match.