Gmail integration

This page documents precisely what Unified E box asks Google for, why each permission is necessary, and what we do and do not do with the data we receive.

Last updated September 21, 2026

Summary

Unified E box is an external OAuth application. Each member connects their own personal Gmail account through Google’s official consent flow and can withdraw that access at any time. We request three scopes. Two of them are classified by Google as sensitive and one as restricted.

We never handle Google passwords

Authorization happens entirely on Google’s own domain. Unified E box never sees, asks for, or stores a Google Account password, and it cannot bypass two-factor authentication.

Scopes we request

Each scope below is requested at the moment a member connects a mailbox, and is shown to them by Google before they approve. The classifications are Google’s own, taken from the published Gmail API scope reference.

https://www.googleapis.com/auth/gmail.modifyrestricted

What it permits. Read messages, threads, and mailbox history, and change the labels applied to them. It does not permit permanently deleting messages or bypassing the trash.

Why we need it

  • Fetch the messages and threads that the unified inbox displays.
  • Run an incremental sync so the inbox reflects the mailbox without re-downloading it.
  • Subscribe to mailbox change notifications so new mail appears without constant polling.
  • Apply and remove the UNREAD label when a member marks a conversation read or unread.
  • Apply and remove the STARRED label when a member stars or unstars a conversation, and show stars applied in Gmail itself.
  • Save an email the member is writing as a draft in their Gmail Drafts, update it as they type, and delete it when they send or discard it.
  • Download an attachment on demand when a member opens it.

Gmail API methods we call

users.getProfileusers.messages.listusers.messages.getusers.messages.attachments.getusers.history.listusers.threads.modifyusers.drafts.createusers.drafts.updateusers.drafts.deleteusers.watchusers.stop

What we do not do with it

  • Permanently deleting a member's messages.
  • Changing Gmail settings, filters, forwarding, or signatures.
  • Creating, renaming, or deleting label definitions in the connected mailbox.
https://www.googleapis.com/auth/gmail.sendsensitive

What it permits. Send mail as the connected account. It grants no read access on its own.

Why we need it

  • Send a reply or a new message that the member composes in the application.
  • Thread the reply correctly onto the existing conversation in Gmail.

Gmail API methods we call

users.messages.send

What we do not do with it

  • Sending mail that a member did not compose and submit.
  • Bulk or automated sending on a member's behalf.
https://www.googleapis.com/auth/userinfo.emailsensitive

What it permits. Read the email address and the stable account identifier of the signed-in Google Account.

Why we need it

  • Identify which mailbox just completed the consent flow, so the resulting credentials are bound to the correct account record.
  • Display the connected address on the Accounts page so a member can tell their mailboxes apart.
  • Prevent the same mailbox from being connected twice.

Gmail API methods we call

oauth2.userinfo.get

What we do not do with it

  • Reading contacts or any profile field beyond those disclosed here.
https://www.googleapis.com/auth/userinfo.profilenon-sensitive

What it permits. Read the basic public profile of the signed-in Google Account: name and profile photo.

Why we need it

  • Show each connected mailbox's own profile photo in the mailbox list, so a member can tell their mailboxes apart at a glance.

Gmail API methods we call

oauth2.userinfo.get

What we do not do with it

  • Reading any profile field other than the photo.
  • Showing the photo to anyone outside the member's own organization.
https://www.googleapis.com/auth/calendar.eventssensitive

What it permits. View and edit events on the calendars the signed-in Google Account can access. It does not permit changing calendar settings or sharing.

Why we need it

  • Show the connected account's upcoming events on the Calendar page, beside its mail.
  • Create an event, and invite guests to it, when a member schedules one from the Calendar page.

Gmail API methods we call

calendar.events.listcalendar.events.insert

What we do not do with it

  • Changing or deleting events that already exist.
  • Reading any calendar other than the account's primary calendar.
  • Changing calendar settings, sharing, or access rules.

Scopes we deliberately do not request

Minimum scope is a design constraint, not an afterthought. These are permissions a mail application might plausibly ask for, and the reason we do not.

ScopeWhy we decline it
https://mail.google.com/Grants full IMAP and SMTP access plus permanent deletion. Nothing in the product needs it, and it would let us destroy mail irreversibly.
https://www.googleapis.com/auth/gmail.readonlyRedundant. The read access we need is already covered by gmail.modify, so requesting both would add a second restricted scope for no additional capability.
https://www.googleapis.com/auth/gmail.labelsNot requested. We only add and remove Gmail's built-in UNREAD and STARRED labels on existing threads, which gmail.modify already permits. We never create or manage label definitions.
https://www.googleapis.com/auth/gmail.settings.basicWe never read or change mailbox settings, filters, forwarding rules, or signatures.
https://www.googleapis.com/auth/contactsWe do not read the Google Contacts address book. Recipients are typed by the member.

The authorization flow, step by step

  1. A member selects Connect Gmail inside the workspace. We create a single-use, server-side state token bound to that member, which expires in ten minutes.
  2. We redirect the member to Google’s consent screen with the three scopes listed above, requesting offline access so that background sync can continue without re-prompting.
  3. Google shows the member which permissions are being requested and for which account.
  4. The member approves or denies. If they deny, no tokens are issued and nothing is stored.
  5. On approval, Google redirects back with an authorization code. We verify the state token, reject anything replayed or expired, and exchange the code for tokens.
  6. We check that the grant actually includes the scopes the product needs. If Google returned a partial grant, we reject the connection rather than operate with a half-working mailbox.
  7. We call oauth2.userinfo.get once to learn which mailbox just authorized, so the tokens are bound to the correct account record. This is the only trustworthy source of that identity.
  8. Tokens are encrypted with AES-256-GCM and stored. The initial sync begins, and a Gmail watch is registered so future changes arrive as notifications.

How synchronization works

After the first sync, Unified E box does not repeatedly download the mailbox. It registers a Gmail watch and receives a notification when the mailbox changes, then asks Gmail for just the history since the last known point using users.history.list. This keeps our request volume proportional to actual activity rather than to the number of connected accounts, and it respects Gmail API usage limits.

Gmail watches expire after seven days, so a scheduled job renews them. If a member revokes access at Google, the next refresh fails, and we mark the account as requiring re-authorization and stop calling the Gmail API for it.

What we store

We store a working copy of the synced mail so the interface can render and search it quickly. The table below is a complete description of the Gmail-derived data we retain.

CategoryWhat it includesWhy
Message contentSubject, snippet, plain-text and HTML bodies, sender and recipient addresses, and timestamps for the messages we sync.The inbox renders conversations and searches across them without re-fetching from Gmail on every keystroke.
Thread metadataGmail thread and message identifiers, message counts, read state, and the RFC 5322 headers needed to thread replies correctly.Keeps the application in sync with Gmail and makes replies land in the right conversation.
Attachment metadataFile name, MIME type, and size. Attachment bytes are not stored; they are fetched from Gmail on demand when a member opens one.Lets the interface list attachments without holding copies of their contents.
OAuth credentialsThe refresh token and the current access token, encrypted at rest with AES-256-GCM, plus the granted scopes and expiry time.Maintains the authorized connection so background sync continues without prompting on every request.
Account recordsThe connected Gmail address, Google's stable account identifier, and the connection status.Identifies the mailbox and surfaces connection problems to the member.
Audit recordsWhich member connected or disconnected a mailbox, and when.Security review and abuse investigation.

Attachment contents are not stored

We keep the file name, type, and size so the interface can list an attachment. The bytes are fetched from Gmail on demand when a member opens the file, and are streamed to that member rather than retained.

What we write back to Gmail

There are exactly five ways Unified E box changes anything in a connected Google account.

  • Read state. When a member marks a conversation read or unread, we add or remove Gmail’s built-in UNREAD label on that thread.
  • Stars. When a member stars or unstars a conversation, we add or remove Gmail’s built-in STARRED label on that thread.
  • Drafts. While a member writes an email, we save it in their Gmail Drafts with users.drafts.create and keep it current with users.drafts.update. When they send or discard it, we remove that draft with users.drafts.delete. We only touch drafts we created.
  • Sending. When a member writes a reply or a new message and submits it, we send it through users.messages.send from their own connected account.
  • Calendar events. When a member creates an event on the Calendar page, we add it to that account’s primary Google Calendar with calendar.events.insert, inviting the guests they list. We never change or delete existing events.

We do not delete mail, move it to trash, archive it in Gmail, create or modify label definitions, or alter mailbox settings. The scopes we hold do not permit permanent deletion, and we did not request one that would.

Disconnecting

A member can disconnect a mailbox from the Accounts page at any time. When they do, we ask Google to revoke the refresh token and we delete the stored credentials outright. After that we cannot call the Gmail API for that mailbox at all. They can equally revoke us from their Google Account permissions page, which has the same effect on our access.

Disconnecting is not the same as deleting

Disconnecting stops all future access and destroys the stored credentials, but by design it leaves the already-synced mail in the workspace so the team keeps its history of conversations. If you want that stored content erased as well, use the data deletion process, which removes it.

Limited Use

Unified E box’s use of information received from Google APIs adheres to the Google API Services User Data Policy, including the Limited Use requirements. In practice that means Gmail data is used only to provide the features described on this page, it is not transferred except as needed to run those features or to meet a legal obligation, it is never used for advertising, and it is never sold.

Human access to message content

Our staff do not read members’ Gmail message content. The narrow exceptions are the ones the policy allows: when a member explicitly asks us to look at a specific message to resolve a support problem, when it is necessary to investigate a security incident or abuse, or when we are legally required to. Any such access is limited to what the situation requires.

Verification status

Because gmail.modify is a restricted scope, this application is subject to Google’s OAuth verification process, which includes an independent security assessment for applications that keep restricted-scope data. We have designed the application to meet those requirements and are submitting it for review. We do not claim to be approved, verified, or certified by Google, and we will not describe ourselves that way unless and until that status is actually granted.

Reviewers may also find the OAuth review notes useful; they collect the scope justifications, the demo walkthrough, and our contact details in one place.