Security
How Inbox Triage handles your credentials, your mail, and your agent. Every line here matches shipped behavior.
Credentials
| Control | How it works |
|---|---|
| No credentials in chat | Every connect flow hands you a link you open yourself: a Google or Microsoft sign-in page, or a masked password form. The secret goes straight from that page into encrypted storage, never through a tool argument or your agent's context. |
| Encrypted at rest | OAuth refresh tokens and mailbox app-specific passwords are stored encrypted with AES-256-GCM under a server master key (Fly secrets in production). We store those credentials because sync needs them, and we would rather say so than imply we hold nothing. |
| Tested before stored | An iCloud or IMAP password is tested live against the mail server before it is accepted. A failed test is rolled back and nothing is kept. |
| Agent API keys hashed | Only a SHA-256 hash is stored. The raw key is shown once, at creation. |
| Revoke any time | Disconnecting an inbox from Account deletes the inbox record and the encrypted mailbox credential immediately. Revoking an agent API key cuts that agent's access without touching mailbox secrets. |
Your mail
| Control | How it works |
|---|---|
| Read-only sync | Reading mail for triage never marks it read on the server. |
| Triage window | Only the newest ~300 messages per selected folder are synced for iCloud/IMAP/Microsoft (~40 for Gmail): INBOX, Sent, and Drafts by default. Trash and Spam are never synced. |
| What we store | Headers, a plain-text body excerpt for the synced window, and attachment names and sizes. Attachment bytes are not stored. They are streamed once, on request, when your agent asks for them. |
| What we don’t store | Your full mailbox history, attachment file contents, or your regular Apple ID / Google / Microsoft account password (OAuth or app-specific passwords only). |
| Never used for training | Your mail is never used to train any AI model. We do not sell mail content. |
Your agent
| Control | How it works |
|---|---|
| Draft first, then approve in chat | The default write path creates a draft in your mailbox. Account
sendEnabled defaults to off until you opt in. Sending only happens
after you enable send and approve in chat (send_draft): IMAP/iCloud via SMTP,
Gmail via users.drafts.send. There is no silent auto-send. An operator-only
immediate-send switch exists for iCloud and IMAP. It is off by default and is not the product send path. |
| Gmail labels | Label apply/remove, star, and archive use the gmail.modify scope with
explicit message and label ids, a per-call batch cap, and a required chat confirmation
for archive and bulk changes. We do not request the restricted
mail.google.com scope. |
| Audit of sensitive actions | Connect (OAuth), disconnect, draft create, approve-in-chat send, trash, and Gmail label/archive/star changes are recorded in the account activity log. It is not a security monitoring system. |
| Prompt-injection guard | Message bodies returned to an agent via get_message are wrapped as
untrusted, quoted data with an instruction not to follow anything inside. |
| Trash is reversible | trash_message moves a message to Trash/Deleted Items. It is never a
permanent delete. |
| Demo data until connected | An inbox with no credential on file shows demo messages (every
sender ends in .test) so you can try everything before connecting anything
real. |
Trust FAQ
What do you store?
Encrypted mailbox credentials (OAuth tokens or IMAP app-specific passwords), a small synced window of message metadata and plain-text bodies (~300 per selected folder for iCloud/IMAP/Microsoft, ~40 for Gmail), hashed agent API keys, and a short account activity log (connect, disconnect, sync errors, key revoke). See also the Privacy page.
What don’t you store?
Attachment bytes, your full mailbox, any password typed in chat (no connect flow asks for one), or your primary Apple ID / Google / Microsoft login password.
How do I disconnect?
On Account, use Disconnect on an inbox, which deletes the stored credential, or Revoke on an agent API key. To remove access on the provider's side too, see the steps below.
How do I remove Inbox Triage from my Google, Microsoft, or Apple account?
Disconnecting an inbox or deleting your account removes what we store. Your mail provider keeps its own record that you allowed Inbox Triage in, and you can remove that too:
- Google: open Google Account, Third-party connections, choose Inbox Triage, then Delete all connections.
- Microsoft (personal account): open Apps and services, choose Inbox Triage, then Remove these permissions.
- Microsoft (work or school account): open My Apps, or ask your IT admin to remove Inbox Triage.
- iCloud: open Apple Account, go to Sign-In and Security, then App-Specific Passwords, and revoke the one you made for Inbox Triage.
- Other IMAP mail: delete or change the app password you gave Inbox Triage in your mail provider's settings.
Do you train on my mail?
No. Mail is never used to train models.
Is this HIPAA / SOC 2 / “bank-grade”?
No. HIPAA is out of scope. We do not hold SOC 2 today. We publish the controls we ship. We do not claim certifications or uptime numbers we do not have.
What Google permissions do you ask for?
Gmail scopes: gmail.readonly (sync), gmail.compose (drafts +
approve-in-chat send via draft send), and gmail.modify (labels / archive /
star). We do not request mail.google.com. After a scope change you may need
to reconnect (Google re-consent). While the Google app is in Testing mode, refresh tokens are short-lived
and you may need to reconnect about every seven days. Google's production verification is a later step and is stricter for
mail scopes.
More detail: Privacy · Terms · iCloud connect (app-specific password) · Docs.