Guide

Multi-Tenant Agent Inboxes

Give every SaaS customer its own AI agent inbox. How to address, route, and isolate one managed mailbox per tenant — and when a shared inbox is enough.

Written by Caleb Geene Director, Site Reliability Engineering

VerifiedCLI 3.1.20 · Nylas managed · last tested June 14, 2026

What is a multi-tenant agent inbox architecture?

A multi-tenant agent inbox architecture gives each customer of a SaaS product its own managed agent inbox, so the AI agent serving that customer reads and sends only their mail. The inbox address itself is the isolation boundary: tenant acme gets acme@yourapp.nylas.email, and nothing the agent does can reach another tenant's inbox. One workspace holds many accounts.

One application provisions a separate agent inbox per tenant: acme, globex, and initech each get an isolated managed mailbox with no shared stateYour applicationone workspaceacme@app.nylas.emailisolated inboxglobex@app.nylas.emailisolated inboxinitech@app.nylas.emailisolated inbox

This is the email equivalent of a per-tenant database schema. Instead of one shared mailbox with a tenant column every query must filter on, each tenant has a physically separate inbox, so a routing bug can't leak one customer's mail to another. The trade-off is account count, which is why the decision below matters once you pass a few hundred tenants.

Why give each tenant its own agent inbox?

Per-tenant inboxes isolate failure, data, and blast radius — the core goal of tenant isolation in any SaaS design. A misbehaving agent can only touch the one inbox it owns, a compromised tenant can't read another's threads, and every customer gets a clean per-tenant audit trail with no filtering. Suspending a single tenant is one grant operation that leaves every other tenant untouched.

Isolation also shrinks the prompt-injection surface. With a shared inbox, one poisoned message sits in the same queue as every tenant's mail, so an injection that escapes a filter has the whole customer base in reach. With per-tenant inboxes, the same payload is trapped in one account that holds only that tenant's data — the blast radius is exactly one customer, not thousands.

How do you address one inbox per tenant?

Derive each address from a stable tenant slug, not a display name, so it never changes when the customer renames their company. Provision the inbox at signup with nylas agent account create, store the returned grant against the tenant id, and you have a deterministic mapping from tenant to inbox. For bulk-creating hundreds of these idempotently, see the provisioning-at-scale guide below.

# Provision a tenant's inbox at signup, keyed by a stable slug
nylas agent account create acme@yourapp.nylas.email --json

# List the fleet to reconcile inboxes against your tenant table
nylas agent account list --json

Keep the slug-to-grant mapping in your own database as the source of truth. The account list output lets you reconcile that table against the live fleet, so an inbox that exists without a tenant row — or a tenant without an inbox — surfaces in one diff rather than a support ticket.

How does inbound mail route to the right tenant?

Routing is implicit: because each tenant has a separate inbox, the inbox a message arrives in is the tenant it belongs to. There is no shared queue to demultiplex and no tenant-id header to trust. The agent process for tenant acme reads only the acme grant, so it physically cannot pull another tenant's mail.

The nylas email list --unread --json command scopes to whichever grant the agent runs under, so the same command serves every tenant without a tenant filter in the query. Each grant carries its own OAuth access token, valid for up to 3,600 seconds and invalidated the moment that grant is revoked, so isolation holds at the credential layer too. That removes the most common multi-tenant bug entirely — a forgotten WHERE tenant_id = clause can't leak data that was never in the same inbox.

# The agent runs under one tenant's grant; the read is already scoped
nylas email list --unread --json

When should you use a shared inbox instead?

Per-tenant inboxes aren't free. The free tier covers 5 accounts, and at tens of thousands of tiny or free-plan tenants the account count and cost outgrow the isolation benefit. For that long tail, a shared inbox with a tenant tag on each message is the pragmatic choice — you trade physical isolation for a logical one you enforce in code, one of the standard multi-tenant architecture models.

A workable rule: give paid tenants their own inbox and pool free-tier tenants into a shared inbox keyed by a reply-to tag or a plus-address. You keep hard isolation where the data is sensitive and accept logical isolation where the volume is high and the stakes are low. The cost of the shared path is that one filtering bug can cross tenants, so the tagging logic needs the same care a shared database schema does.

Next steps