Source: https://cli.nylas.com/guides/outlook-oauth-ai-agents

# Outlook OAuth for AI Agents: Graph Setup

You want an AI agent that reads and sends Outlook email unattended. Microsoft Graph says: register an Entra app first, then choose between delegated and application permissions, survive a 60-90 minute access-token lifetime, and convince a tenant admin to consent. This guide walks the OAuth decisions in order, shows where each one bites an autonomous agent, and ends with the one-command path that skips the registration entirely.

Written by [Hazik](https://cli.nylas.com/authors/hazik) Director of Product Management

Updated June 6, 2026

> **TL;DR:** Graph email automation needs an Entra app registration plus `Mail.Send` (and usually `Mail.Read`). Delegated permissions act as one signed-in user; application permissions run unattended but default to **every mailbox in the tenant** until an admin scopes them. Access tokens last 60-90 minutes, so agents must refresh mid-task. The CLI alternative: `nylas auth login --provider microsoft`, then send with one command.

> **Disclosure:** Nylas CLI is built by Nylas, Inc. This comparison reflects our testing and product understanding as of June 6, 2026.

Command references used in this guide: [`nylas auth login`](https://cli.nylas.com/docs/commands/auth-login), [`nylas email send`](https://cli.nylas.com/docs/commands/email-send), and [`nylas email list`](https://cli.nylas.com/docs/commands/email-list).

## What does an AI agent need to automate Outlook email?

An agent that automates Outlook email needs three things from Microsoft's side: an app registration in Microsoft Entra, Graph API permissions for mail, and a token flow that works without a human at the keyboard. Per the [sendMail reference](https://learn.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0), the least-privileged permission for sending is `Mail.Send` across all 3 permission types, and a successful send returns `202 Accepted`.

Reading is a separate permission. `Mail.Read` covers listing and fetching messages, `Mail.ReadWrite` adds drafts and moves; both are documented in the [Graph permissions reference](https://learn.microsoft.com/en-us/graph/permissions-reference). An email agent that triages and replies typically needs 2 permissions, not 6 — granting `Mail.ReadWrite` plus `Mail.Send` when `Mail.Read` plus `Mail.Send` would do widens the blast radius of a prompt-injected or buggy agent for no benefit.

## Should an agent use delegated or application permissions?

Delegated permissions act on behalf of one signed-in user; application permissions act as the app itself with no user present. Microsoft's [service app documentation](https://learn.microsoft.com/en-us/graph/auth-v2-service) describes the application category as "background services (daemons) that run on a server without a signed-in user" — which is exactly what an unattended email agent is. The catch: application permissions require tenant admin consent before the first token is issued.

The sharper catch is scope. An application-permission `Mail.Send` grant covers every mailbox in the tenant by default, not just the agent's — in a 5,000-seat tenant, that's 5,000 send identities behind one credential. Microsoft's [mailbox-scoping documentation](https://learn.microsoft.com/en-us/graph/auth-limit-mailbox-access) explains how admins restrict an app to specific mailboxes through Exchange Online's RBAC for Applications, which the page notes "replaces Application Access Policies." Treat that scoping step as mandatory: an agent with tenant-wide send rights is one prompt injection away from impersonating the CEO.

| Factor | Delegated | Application |
| --- | --- | --- |
| Runs unattended | Only while refresh token stays valid | Yes (client credentials flow) |
| Mailbox reach | The signed-in user only | Whole tenant until scoped via RBAC |
| Consent | User (admin for some scopes) | Tenant admin, always |
| Who grants the permission | The user, at sign-in | An administrator, directly to the app |

For a single-user agent — a personal triage bot, a founder's scheduling assistant — delegated permissions with a refresh token are the right shape. Application permissions fit fleet-style automation, like a support agent that drafts replies from a shared mailbox, and only after the RBAC scoping is in place.

## How do access token lifetimes affect long-running agents?

A Microsoft Entra access token doesn't last a workday. According to the [token lifetimes documentation](https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes), each access token is "assigned a random value ranging between 60-90 minutes (75 minutes on average)." Any agent task that can outlive 60 minutes — a nightly inbox sweep, a long research loop with email checkpoints — must refresh tokens mid-task or fail with 401s partway through.

The standard fix is using MSAL (or any OAuth library) with a token cache and calling its acquire-token method before every Graph request rather than storing the bearer string. The library returns the cached token while it's valid and silently refreshes when it isn't. Agents that bypass this — copying a token into an environment variable at startup, a pattern that appears in many quick-start tutorials — work in the demo and break on the first run longer than the token's random 60-90 minute fuse.

## What is the faster path for a developer agent?

The CLI path replaces the app registration, consent flow, and token plumbing with one browser login. `nylas auth login --provider microsoft` runs the OAuth flow once, stores the grant, and refreshes tokens internally from then on. The agent shells out to commands with `--json` output instead of holding Graph credentials at all, which means there's no bearer token in the agent's context for a prompt injection to exfiltrate.

```bash
# One-time: connect the Outlook / Microsoft 365 account
nylas auth login --provider microsoft

# Agent read path: unread messages as JSON
nylas email list --unread --json --limit 20

# Agent send path: explicit, confirmable, scriptable
nylas email send --to ops@example.com \
  --subject "Daily triage summary" \
  --body "12 unread, 3 need replies. Details attached below." \
  --yes
```

The trade-off is granularity: Graph gives you per-permission control an admin can audit in Entra, while the CLI's grant covers the connected mailbox's mail surface. For multi-provider agents the calculus flips — the same 2 commands above work unchanged on Gmail, Exchange, Yahoo, iCloud, and IMAP accounts, where a Graph-only integration would need a parallel Gmail API implementation. The [email API comparison for agents](https://cli.nylas.com/guides/email-apis-for-ai-agents-compared) scores these paths side by side.

## How do you keep an Outlook agent's send path safe?

Whichever auth path you pick, keep the send action behind a separate, narrower control than the read path. Some teams keep Outlook agents draft-only for the first 30 days, then enable send after reviewing transcripts and recipient errors — the rollout pattern described in the [Outlook MCP guide](https://cli.nylas.com/guides/outlook-mcp-server-ai-agents). On the Graph side that means delaying the `Mail.Send` grant; on the CLI side it means the agent prepares commands a human runs.

Containment matters because an Outlook agent holds all three legs of the lethal trifecta: private data (the mailbox), untrusted content (every inbound message), and external communication (the send permission). An agent can be talked into misusing any capability it holds, but it can't prompt its way past a rule it doesn't control — which is why send restrictions belong in the auth layer, not the system prompt. The [rogue-agent containment guide](https://cli.nylas.com/guides/stop-ai-agent-going-rogue) covers that defense layer, and the [audit logging guide](https://cli.nylas.com/guides/audit-ai-agent-activity) shows how to keep a replayable record of every command an agent ran.

## Next steps

- [Outlook MCP server options](https://cli.nylas.com/guides/outlook-mcp-server-ai-agents) — hosted connectors vs Graph tools vs local CLI MCP for agents
- [Microsoft Graph email quickstart](https://cli.nylas.com/guides/microsoft-graph-email-quickstart) — the full Graph code path if you do own the app registration
- [Email APIs for AI agents compared](https://cli.nylas.com/guides/email-apis-for-ai-agents-compared) — Graph vs Gmail API vs IMAP vs CLI, scored for agent use
- [Send Outlook email from the CLI](https://cli.nylas.com/guides/send-outlook-email-cli) — the send workflow this guide's agent path builds on
- [Full command reference](https://cli.nylas.com/docs/commands) — every flag and subcommand documented
