Microsoft (Graph: Outlook mail and calendar)
Registering a multitenant Entra ID app and getting a token for your own account takes under an hour and costs nothing. The catch is on the customer side: since the 2025 Microsoft-managed consent policy (the default for new tenants), ordinary users cannot consent to Mail.Read or Calendars.ReadWrite at all, so each clinic's Microsoft 365 admin must grant admin consent once. Publisher verification (free, needs a verified Microsoft AI Cloud Partner Program account, about 3-5 business days) removes the 'unverified' warning but does not lift that admin-consent requirement.
Review: No app review by Microsoft. Publisher verification (Partner Center business verification + linking the Partner One ID) is strongly recommended; each customer tenant's admin must grant consent for mail/calendar scopes under the default policy.
Timing: 1-2 weeks (Partner Center business verification is typically 3-5 business days; then per-customer admin consent).
Cost: free (publisher verification and Partner Program membership are free; Microsoft 365 Certification audit is paid and optional)
Before you start
- for buildMicrosoft Entra work/school tenant (e.g. one for iskaria.com) and an account with at least the Application Developer role. Apps registered with a personal Microsoft account cannot be publisher verified.sourceds1s4
- for buildHTTPS redirect URI on a server (Web platform); http://localhost is accepted for local development✓ Iskaria has itsourceds5
- for launchMicrosoft AI Cloud Partner Program account (Partner One ID of the partner global account) that has passed Partner Center verification: email, identity, employment and business (legal registration) checks. Profile: businessVerification.microsoftPartnerId is null and legalEntity is null, so this is MISSING.✗ missing in profilesourceds4s7
- for launchLegal entity registration documents (certificate of incorporation, business licence) whose name and address match the Partner Center account exactly. Profile legalEntity is null: MISSING.✗ missing in profilesourceds7
- for launchPublisher domain set on the app, not *.onmicrosoft.com; the Partner Center verification email's domain must match it or be a DNS-verified custom domain in the Entra tenant. Profile only records Google Search Console verification for iskaria.com; iskaria.com must also be DNS-verified in the Entra tenant.✓ Iskaria has itsourceds4
- for launchBusiness email on the company domain for the Partner Center primary contact (not a free/personal address)✓ Iskaria has itsourceds7
- for launchPrivacy statement and terms of service URLs (shown in the consent prompt via Branding & properties)✓ Iskaria has itinferred
No separate test mode: the app works immediately for your own tenant and for any tenant whose admin consents. In tenants with the Microsoft-managed (default) policy, non-admin users cannot self-consent to Mail.Read / Calendars.ReadWrite; test with an account that is an admin in its tenant (e.g. your own iskaria.com tenant).
Who does what
- Write the OAuth authorization-code flow, token storage and refresh code
- Prepare the exact redirect URIs, scope list and branding text to paste
- Generate a self-signed certificate for testing and the code to use certificate credentials
- Draft the clinic-facing admin-consent instructions and the Publisher Attestation answers
- Draft Graph calls for /me/messages, /me/sendMail and /me/events and test them once a token exists
- Sign in to the Entra admin center (MFA) and create the registration and credentials
- Add and DNS-verify iskaria.com in the Entra tenant
- Enrol in the Microsoft AI Cloud Partner Program and upload legal/identity documents
- Enter the Partner One ID to mark the app publisher verified
- Get each clinic's Microsoft 365 admin to grant admin consent
Steps
Sign in to the Microsoft Entra admin center as at least Application Developer, in your company tenant. Entra ID > App registrations > New registration. Name: Iskaria. Supported account types: 'Multiple Entra ID tenants' (organisations only; clinics use work accounts). Pick 'Any Entra ID Tenant + Personal Microsoft accounts' only if you also want Outlook.com users. Register, then record the Application (client) ID.
https://entra.microsoft.comName Iskaria Supported account types Multiple Entra ID tenants App registration > Authentication > Add Redirect URI > Web. Add https://app.iskaria.com/api/oauth/microsoft/callback and, for development, http://localhost:3000/api/oauth/microsoft/callback. Configure.
Redirect URI ["https://app.iskaria.com/api/oauth/{provider}/callback","http://localhost:3000/api/oauth/{provider}/callback"] Certificates & secrets. For development: Client secrets > New client secret; lifetime is capped at 24 months and Microsoft recommends under 12; copy the Value immediately (never shown again). For production Microsoft says not to use secrets: upload a certificate (.cer/.pem/.crt) and keep the private key in a vault, or use a federated credential. Put a calendar reminder before expiry either way.
API permissions > Add a permission > Microsoft Graph > Delegated permissions: User.Read (default), offline_access, Mail.Read, Mail.Send, Calendars.ReadWrite. Request the same scopes in the authorization request (https://graph.microsoft.com/Mail.Read etc.). Do not add application permissions unless you need unattended access to every mailbox.
Branding & properties: logo, home page, terms and privacy URLs, and set the publisher domain to iskaria.com (requires iskaria.com to be added and DNS-verified as a custom domain in the tenant; a TXT record).
Home page URL https://iskaria.com/ Terms of service URL https://iskaria.com/terms Privacy statement URL https://iskaria.com/privacy Logo missing: logo.square512PngProfile has no exported PNG yet Publisher domain ["iskaria.com"]
- 6Get your first token in your own tenantAgent drafts, you submit15-30 mininferred
Implement the authorization-code flow against the /common (or /organizations) endpoint, sign in with your own admin account, consent, and call GET /me/messages and /me/events. Check the refresh token arrives (requires offline_access).
- 7Join the Microsoft AI Cloud Partner Program and pass verificationYou1 h hands-on, 3-5 business days waitsourceds7
Enrol in Partner Center with a Global Admin of the tenant. Provide legal business name/address matching registration documents, a business-domain email, identity document, and domain registration documents. Microsoft runs email, identity, employment and business checks; typically 3-5 business days, longer if more information is requested.
https://partner.microsoft.com/membershipLegal business name missing: legalEntityMISSING in profile Primary contact email ibrahim@iskaria.com Country India / UAE (clients in UAE and Kuwait)Must match the registered entity's jurisdiction Sign in with MFA as Application Administrator / Cloud Application Administrator who is also Partner Admin or Account Admin in Partner Center. App registrations > the app > Branding & properties > Add Partner ID to verify publisher > enter the Partner One ID of the partner global account (not a location ID) > Verify and save. The blue verified badge then shows on consent prompts.
Partner ID missing: businessVerification.microsoftPartnerIdMISSING in profile For each customer tenant on the default 'Let Microsoft manage your consent settings' policy, a Global/Application/Cloud Application Administrator of that tenant must grant admin consent (sign in and tick 'Consent on behalf of your organization', or approve via that tenant's admin consent workflow). Provide clinics a short admin-consent instruction page.
Self-assessment of security, data handling and compliance published on Microsoft's App Compliance pages; most take about an hour. Full Microsoft 365 Certification is a yearly paid third-party audit (Claranet) and only worth it if enterprise customers demand it.
Scopes an agent typically needs
| Scope | Used for | Review tier | Evidence |
|---|---|---|---|
| offline_access | Refresh tokens so the assistant keeps working without the clinic signing in again One of the five permissions Entra classifies as low impact by default. | basic | inferred |
| Mail.Read | Read patient emails in the clinic mailbox so the assistant can draft replies Delegated, not admin-consent-required by Graph itself, but EXCLUDED from user consent by the Microsoft-managed default policy: needs tenant admin consent in most customer tenants. | sensitive | sourceds2 |
| Mail.Send | Send patient follow-up emails as the signed-in staff member Not on the Microsoft-managed exclusion list as of the 2026-01-22 doc, so users can self-consent unless their admin restricted consent. Moot when requested together with Mail.Read. | sensitive | sourceds2 |
| Calendars.ReadWrite | Read availability and create/update appointment events Graph lists AdminConsentRequired = No for delegated, but the Microsoft-managed default policy excludes it from user consent. | sensitive | sourceds6s2 |
| User.Read | Sign-in and basic profile (which staff member connected) Added to every new registration by default. | basic | sourceds1 |
What can slow you down or block approval
'Let Microsoft manage your consent settings' (microsoft-user-default-recommended) is the default for new tenants and lets users consent to anything EXCEPT a list that includes Mail.Read, Mail.ReadWrite, Calendars.Read, Calendars.ReadWrite, Contacts.ReadWrite, Files.Read.All and others. Rolled out from mid-2025 (files/sites first, then Exchange/Teams permissions around Oct-Nov 2025). Publisher verification does not change this.
Workaround: Plan onboarding around a clinic admin granting tenant-wide admin consent; small clinics often have one IT person or an MSP. Or drop Mail.Read and use only Mail.Send if reading is not needed.
Since November 2020, if risk-based step-up consent is enabled, users cannot consent to multitenant apps registered after 8 Nov 2020 that are not publisher verified and request more than sign-in/profile; a warning says the app is from an unverified publisher. Tenants using 'Allow user consent for apps from verified publishers' also block you until verified.
Workaround: Complete publisher verification before onboarding external clinics.
Verification checks that the business is legally registered at the stated address and that the primary contact is an employee, using formation documents and domain registration documents. The profile has no legalEntity; a mismatch between documents and account (spelling, abbreviations) causes rejection.
Workaround: Use the exact registered name/address from the UAE or Indian incorporation certificate; appeal if rejected.
Publisher domain cannot be *.onmicrosoft.com, and the Partner Center email domain must match it or a DNS-verified custom domain in the tenant. Google Search Console verification does not count.
Workaround: Add iskaria.com as a custom domain in the Entra tenant (TXT record) before starting verification.
Secrets cannot exceed 24 months; Microsoft recommends under 12 and says secrets should not be used in production. An expired secret silently breaks every clinic's connection.
Workaround: Use a certificate stored in a key vault, monitor expiry, and keep two overlapping credentials during rotation.
What we checked
| Claim | How | Result |
|---|---|---|
| Since 2020 the default tenant policy blocks user consent to apps from unverified publishers The Nov 2020 block applies only where risk-based step-up consent is enabled. The current default (Microsoft-managed policy) instead blocks user consent to Mail.Read/Calendars.* regardless of publisher verification. | Fetched publisher-verification-overview and manage-app-consent-policies | corrected |
| Mail.Read and Calendars.ReadWrite are user-consentable delegated permissions Technically user-consentable, but excluded from user consent by the default policy since the 2025 rollout. | Graph permissions reference (Calendars.ReadWrite AdminConsentRequired = No) cross-checked against the Microsoft-managed exclusion list on Learn and a Nov 2025 community post | corrected |
| Client secrets max 24 months Microsoft also recommends under 12 months and says secrets should not be used in production. | Fetched how-to-add-credentials | confirmed |
| Publisher verification needs an MPN ID MPN is now the Microsoft AI Cloud Partner Program; the field is the Partner One ID of the partner global account, location IDs are rejected. | Fetched publisher-verification-overview and mark-app-as-publisher-verified | corrected |
| Supported account type is called 'Accounts in any organizational directory' Labels are now 'Multiple Entra ID tenants' and 'Any Entra ID Tenant + Personal Microsoft accounts'; navigation is Entra ID > App registrations. | Fetched quickstart-register-app (ms.date 2026-05-14) | corrected |
| Partner Center verification takes days Three to five business days in most cases. | Fetched Partner Center verification process page | confirmed |
| Microsoft-managed default consent policy excludes Mail.Read, Mail.ReadWrite, Calendars.Read/ReadWrite, Contacts.ReadWrite, Files.Read.All...; Mail.Send is not excluded; default for new tenants List also includes MailboxSettings.*, Tasks.*, People.Read, Chat.*, OnlineMeetings.* and EAS/EWS/IMAP/POP for Exchange. Mail.Send absent. | Independent check: re-fetched learn.microsoft.com 'Manage app consent policies' (ms.date 2026-01-22, updated 2026-08-28) on 2026-10-30 | confirmed |
| Client secrets max 24 months; Microsoft recommends under 12 and says secrets should not be used in production | Independent check: re-fetched learn.microsoft.com 'Add and manage app credentials' on 2026-10-30 | confirmed |
| Partner Center business verification typically 3-5 business days | Independent check: not re-fetched; relies on s7 only | unverified |
| OAuth endpoint behaviour (discovery metadata, PKCE, dynamic registration, unknown-client handling) Entra's v2.0 discovery is found only under the tenant path, does not advertise PKCE methods (Entra supports S256 in practice, not shown here) and has no dynamic registration. Unknown client_id on /common/oauth2/v2.0/authorize returns HTTP 200 with an HTML error page. | Endpoint probe: node scripts/probe.ts on 2026-10-30 | confirmed |
- Whether Mail.Send stays user-consentable: the Microsoft-managed exclusion list is updated by Microsoft (with at least 30 days' notice per a community summary) and could grow.
- Which existing customer tenants actually run the Microsoft-managed policy vs. legacy 'Allow user consent for apps' or 'Do not allow user consent'; it varies per tenant and older tenants may differ.
- Partner Center verification for an India/UAE entity: Microsoft states 3-5 business days typical; real-world times with document requests are anecdotally longer and not documented.
- Exact Branding & properties field names were not re-fetched this session.
- offline_access low-impact classification is from a community summary, not the Learn page.
Sources
- s1How to register an app in Microsoft Entra ID · official-docs · accessed 2026-10-30
“For multitenant apps when you want users in any Microsoft Entra tenant to be able to use your application.”
- s2Manage app consent policies (Microsoft recommended user consent policy) · official-docs · accessed 2026-10-30
“This is also the default for a new tenant. The setting's rules are currently: End users can consent for any user consentable delegated permissions EXCEPT”
- s3Add and manage app credentials in Microsoft Entra ID · official-docs · accessed 2026-10-30
“Client secret lifetime is limited to two years (24 months) or less. You can't specify a custom lifetime longer than 24 months.”
- s4Publisher verification overview · official-docs · accessed 2026-10-30
“The developer must have a Partner One ID for a valid Microsoft AI Cloud Partner Program account that has completed the verification process.”
- s5How to add a redirect URI to your application · official-docs · accessed 2026-10-30
“Redirect URIs are configured on the Authentication page in the Microsoft Entra admin center.”
- s6Microsoft Graph permissions reference · official-docs · accessed 2026-10-30
“AdminConsentRequired | Yes | No”
- s7Understand the verification process in Partner Center · official-docs · accessed 2026-10-30
“In most cases, the process takes three to five business days to complete.”
- s8Mark an app as publisher verified · official-docs · accessed 2026-10-30
“Select Add Partner ID to verify publisher near the bottom of the page.”
- s9Configure how users consent to applications · official-docs · accessed 2026-10-30
“we recommend that you allow user consent only for applications that have been published by a verified publisher.”
- s10Microsoft 365 App Compliance Program overview · official-docs · accessed 2026-10-30
“Most attestations can be completed in one hour or less (depending on app/agent framework).”
- s11Microsoft-managed default app consent policy now blocks 20 additional permissions (Topedia) · community · accessed 2026-10-30
“These new permissions are now rolling out and include 20 additional excluded permissions for Outlook Mailbox, Outlook Mail, Outlook Calendar, Teams Chat, and Teams Meetings.”
- s12Endpoint probe, 2026-10-30 · our-test · accessed 2026-10-30
“openid-configuration under /common/v2.0 (root paths 404); scopes_supported [openid, profile, email, offline_access]; no code_challenge_methods_supported field; no registration_endpoint”