Skip to main content
Not shipped. The transport seam is an open pull request (Vexa-ai/vexa#1318) targeting a feature branch, not main. The Graph transport is fixture-proven and has never met a live Exchange server, and the chart does not plumb these variables yet. This page exists so your identity team can start the approval path — the long pole — not because you can deploy it today.
Vexa’s flows tier is driven by a mailbox: people invite an address to a meeting, or write to it. VEXA_MAIL_TRANSPORT picks how Vexa reads it; any other value is a startup error.

gmail and imap

Exchange Online with IMAP enabled is four values: outlook.office365.com:993, smtp.office365.com:587, VEXA_MAIL_SMTP_STARTTLS=1.

graph

Admin runbook — Microsoft Graph

1 · Register an application. Entra ID → App registrations → New registration. Single tenant, no redirect URI. Record the Application (client) ID and Directory (tenant) ID; create a client secret and record its value, not its id. 2 · Grant application permissions. API permissions → Microsoft Graph → Application permissions (not delegated): Mail.ReadWrite (read the inbox, draft the reply) and Mail.Send. Nothing else is required to read a mailbox. Replies are drafted then sent because that is the only way Graph returns the real internetMessageId that keeps a reply in thread. 3 · Grant admin consent for the tenant. Until a Global Administrator (or Privileged Role Administrator) consents, the app authenticates fine and returns 403 on every call. 4 · Scope the app to one mailbox — required. Mail.ReadWrite as an application permission is tenant-wide: without this step the app can read every mailbox in your tenant.
Expect Granted for the vexa mailbox, and run the test against a second mailbox too, expecting Denied — a policy that was created but does not apply looks identical to one that works. Allow a few minutes for propagation. Mint the client secret in the admin’s browser and put it into the cluster Secret from the admin’s terminal. It goes in no ticket, chat or email, Vexa’s included. az login is not your app. The Azure CLI gives you a delegated token as yourself, and delegated calls succeed against mailboxes the application permission does not cover. Test with grant_type=client_credentials and scope=https://graph.microsoft.com/.default. And a fresh registration returning 403 is usually missing consent, not missing permissions.

If you also want Vexa to create Teams meetings

A separate capability with its own approval path; the mail transport never touches the meetings API. Additional application permissions, with admin consent: OnlineMeetings.ReadWrite.All and Calendars.ReadWrite (to place it on the organizer’s calendar). Plus a Teams policy granted to the organizing user:
The organizer is identified by objectId GUID, not by UPN. POST /users/{organizer}/onlineMeetings needs the directory object id; a UPN fails with an invalid-GUID message that reads like a malformed request id. Resolve it once with GET /users/<upn>?$select=id and store the GUID.

Current limits

  • An invite is picked up only if it carries a https://meet.google.com/… link. A Teams-linked Outlook invite is ignored, silently.
  • Invites more than 24 hours in the past are dropped.
  • First boot anchors at the tail; existing mail is never replayed.
  • Delta mode can re-deliver a batch after a crash; de-duplication is by Message-ID.
  • The Graph invite-synthesis path is fixture-proven only.
  • One manual schema change on an existing deployment: ALTER TABLE mail_cursor ADD COLUMN token TEXT;. IMAP works without it; Graph refuses to start rather than rewinding your cursor.
  • The chart does not carry these variables yet.