# OAuth 2.0 vs IMAP auth for email

Source: https://developer.nylas.com/docs/cookbook/use-cases/build/oauth-vs-imap-auth/

You're connecting a user's mailbox and you hit the first fork in the road: ask for their password over IMAP, or send them through an OAuth consent screen. The choice used to be a convenience tradeoff. It isn't anymore. Microsoft, Google, and Yahoo have all turned off password-based access for their hosted accounts, so for the providers most of your users are on, OAuth is the only door that's still open.

This guide compares OAuth 2.0 with IMAP and basic auth (including app passwords), explains why the major providers deprecated password auth, and shows where IMAP credentials still make sense. Both paths land in the same place: a Nylas grant you read and send mail through, no matter which auth method created it.

## What is the difference between OAuth 2.0 and IMAP authentication for email?

OAuth 2.0 authenticates a user through their provider's consent screen and returns a scoped, revocable token your app never sees the password behind. IMAP authentication sends a username and password (or app password) straight to the mail server. OAuth tokens expire and refresh; IMAP credentials stay valid until the user changes them.

The practical difference is blast radius and lifecycle. An OAuth token is scoped to exactly what the user approved, like `Mail.Read`, and a user or admin can revoke it from the provider's security dashboard without touching their password. An IMAP password is all-or-nothing: whoever holds it has full account access, including settings, until it's rotated. OAuth also handles expiry automatically through refresh tokens, while IMAP credentials need manual re-entry whenever they change. With Nylas, both produce a grant, so you call `GET /v3/grants/{grant_id}/messages` the same way regardless of which method connected the account.

## Why did Microsoft and Google deprecate basic auth?

Providers killed basic auth because a stored password is a standing liability: it can't be scoped, can't be revoked without a reset, and survives indefinitely if leaked. Microsoft permanently disabled basic authentication for Exchange Online on October 1, 2022, completing a multi-year rollout. OAuth 2.0 replaced it as the only supported flow for hosted Microsoft 365 mail.

The security math is straightforward. A password sent over IMAP grants full, permanent access and bypasses multi-factor authentication, which made it the favorite target for password-spray and credential-stuffing attacks. OAuth tokens are scoped, time-limited, and revocable, and they respect conditional-access policies. Microsoft documented the full timeline and reasoning in the [deprecation of basic authentication](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online) announcement. Google followed the same path, ending password access for less-secure apps and pushing all Gmail integrations onto OAuth. The pattern is industry-wide now, not a single vendor's decision.

## How does OAuth work differently for Exchange Server versus Microsoft 365?

Microsoft 365 (Exchange Online) uses cloud OAuth through Microsoft Entra: your app requests scopes, the user or a tenant admin consents, and you get a refresh token. On-premises Exchange Server (EWS) has no cloud identity provider, so you connect it through Nylas Hosted auth with `provider=ews` at `GET /v3/connect/auth`, where the hosted page collects the Exchange credentials instead of an OAuth consent.

This is the biggest source of confusion when teams say "Exchange". Hosted Microsoft 365 mailboxes go through the standard OAuth flow at `GET /v3/connect/auth`, the same one Google uses, and benefit from token scoping and revocation. On-premises Exchange Server, which many enterprises still run behind their firewall, predates that model. For those accounts you send the user through `GET /v3/connect/auth` with `provider=ews`; the hosted page collects the Exchange address and, if autodiscovery fails, the server host. If you already hold credentials, the `/v3/connect/custom` Bring Your Own Auth endpoint is the alternative. Microsoft's guidance is explicit: hosted Exchange should use Microsoft Graph (OAuth), and only genuinely on-premises servers should fall back to EWS. The [connect Exchange (EWS) accounts](/docs/cookbook/email/connect-exchange-ews/) guide covers the flow end to end.

## Which OAuth flows are supported for desktop apps that read email?

Desktop and mobile apps should use the OAuth 2.0 authorization code flow with PKCE, because they're "public clients" that can't safely store a client secret. PKCE adds a one-time `code_challenge` and `code_verifier` pair that binds the authorization code to the app that started the flow, blocking code-interception attacks on the redirect.

PKCE is the IETF-recommended pattern for native apps, defined in [RFC 8252 (OAuth 2.0 for Native Apps)](https://datatracker.ietf.org/doc/html/rfc8252). With Nylas, you pass `code_challenge` and `code_challenge_method` on the `GET /v3/connect/auth` request, then exchange the returned code at `POST /v3/connect/token` along with the matching `code_verifier`. The provider's consent screen opens in the system browser, the user approves, and your desktop app receives a grant without ever embedding a secret. For the full native walkthrough, see the [desktop OAuth guide](/docs/cookbook/use-cases/build/desktop-oauth/). Roughly two extra parameters on the auth URL are all PKCE adds.

## OAuth 2.0 vs IMAP auth compared

The table below compares the two auth methods on the dimensions that decide which one you reach for. Both feed the same grant model, so the choice is about provider support and security posture, not about how you call the API afterward.

| Dimension | IMAP / basic auth | **OAuth 2.0 (Nylas grant)** |
| --- | --- | --- |
| **Credential held** | Username + password or app password | **Scoped, revocable token; password never seen** |
| **Hosted Microsoft 365** | Disabled since Oct 1, 2022 | **Supported through Microsoft Entra** |
| **Gmail / Yahoo** | Password access removed | **Supported through provider consent** |
| **Expiry handling** | Manual re-entry on change | **Automatic refresh token** |
| **Revocation** | Reset the password | **Revoke the token, password untouched** |
| **Connect endpoint** | `POST /v3/connect/custom` | **`GET /v3/connect/auth`** |
| **Best for** | Self-hosted IMAP, on-prem EWS | **Google, Microsoft 365, Yahoo, iCloud** |

## Connect an IMAP account when OAuth isn't available

OAuth covers the big providers, but plenty of mail still lives on self-hosted IMAP servers and on-premises Exchange where no consent screen exists. For those, Nylas creates a grant directly from credentials through the Bring Your Own Authentication endpoint, `POST /v3/connect/custom`. You supply `imap_username`, `imap_password`, and optionally `imap_host` and `imap_port`; the API auto-detects the host from the username when you omit it.

The request below creates an IMAP grant from a username and app password. Use it for generic IMAP servers or providers like iCloud (which requires an [Apple app password](https://support.apple.com/en-us/HT204397)). Default IMAP runs on port 993 and SMTP on 465 or 587.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/connect/custom' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "provider": "imap",
    "settings": {
      "imap_username": "user@example.com",
      "imap_password": "<IMAP_APP_PASSWORD>",
      "imap_host": "imap.example.com",
      "imap_port": 993,
      "smtp_host": "smtp.example.com",
      "smtp_port": 587
    }
  }'
```

A password-based grant works exactly like an OAuth grant once created, but it carries the lifecycle cost: if the user changes their password, the grant breaks and you re-collect credentials. There's no refresh token to lean on. That's the honest tradeoff. When the user is on Google, Microsoft 365, or Yahoo, prefer OAuth every time; reach for IMAP credentials only when the provider gives you no OAuth option. For the broader protocol comparison, see [IMAP vs the Email API](/docs/cookbook/email/imap-vs-email-api/).

## Start the OAuth flow for hosted providers

For Google, Microsoft 365, Yahoo, and iCloud, send the user through hosted OAuth at `GET /v3/connect/auth`. Nylas builds the provider consent URL, the user approves the scopes, and the provider redirects back to your `redirect_uri` with an authorization code you exchange for a grant. You never handle the password, and the resulting token refreshes on its own.

This request starts the authorization code flow for a Google account. Set `response_type=code`, point `redirect_uri` at your registered callback, and pass `provider` to skip the provider-picker screen. Add `code_challenge` here when you're building a desktop or mobile client.

```bash
curl --request GET \
  --url 'https://api.us.nylas.com/v3/connect/auth?client_id=<NYLAS_CLIENT_ID>&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&response_type=code&provider=google'
```

After the redirect, exchange the code at `POST /v3/connect/token` to receive the `grant_id`. The scopes you request here decide what the token can reach, so request the narrowest set that covers your features. The [OAuth scopes reference](/docs/cookbook/use-cases/build/oauth-scopes-email-calendar/) lists the exact Gmail and Microsoft Graph scope strings, and the [connect user accounts guide](/docs/cookbook/use-cases/build/connect-user-accounts-oauth/) walks through the full flow and token refresh.


> **Info:** 
> **New to Nylas?** Start with the [quickstart guide](/docs/v3/getting-started/) to set up your app and connect a test account before continuing here.


## What's next

- [Connect user accounts with OAuth](/docs/cookbook/use-cases/build/connect-user-accounts-oauth/) for the full hosted flow, token exchange, and refresh
- [OAuth scopes for email and calendar](/docs/cookbook/use-cases/build/oauth-scopes-email-calendar/) for the exact provider scope strings to request
- [Desktop OAuth with PKCE](/docs/cookbook/use-cases/build/desktop-oauth/) for the native-app flow without a client secret
- [IMAP vs the Email API](/docs/cookbook/email/imap-vs-email-api/) for the protocol-level comparison and when to stay on raw IMAP