Skip to content

Gmail Integration

The Gmail integration enables WhiteLotusAI to retrieve, search, and analyze email data through conversational requests. The inspected implementation also contains email-writing and mailbox-modification capabilities, which must be restricted before the integration can be approved for strict read-only operation.

Documentation status: Source-reviewed. End-to-end behavior, authorization boundaries, and read-only enforcement remain to be verified.

Read-only security requirement

The current implementation includes operations that send or modify email. Do not treat the integration as read-only merely because a request originates from a conversational interface or because a tool requests confirmation. Enforce the policy at the tool registry, dispatch layer, and integration API.

1. Architecture and components

The Gmail integration spans the chat plugin, integration-service handlers, and Gmail client. The chat plugin interprets conversational requests and dispatches operations to the integration service, where credentials and Gmail API requests are handled.

flowchart TD
    U["User request"] --> P["Email chat plugin"]
    P --> R["Conversational response"]

    P --> Q["Intent and query processing"]
    Q --> T["Tool selection and dispatch"]
    T -->|HTTP request| I["Integration service"]

    I --> A["User-specific connection and token resolution"]
    A --> C["Gmail client"]
    C --> G["Google Gmail API"]
    G --> C
    C --> I
    I --> P

    A -.-> S["OAuth and token storage"]
    S -.-> C

    classDef app fill:#e8eaf6,stroke:#5c6bc0,color:#202124
    classDef service fill:#e0f2f1,stroke:#00897b,color:#202124
    classDef external fill:#fff3e0,stroke:#ef8c00,color:#202124

    class P,Q,T,R app
    class I,A,C,S service
    class G external

The diagram represents the documented logical flow, not proof that every path is registered or reachable in the deployed application.

Component Source location Responsibility
Email chat plugin chat/package/app/plugins/email/plugin.py Intent detection, natural-language query processing, tool definitions, and dispatch
Integration handlers integrations/package/app/handlers/integration_handlers.py OAuth lifecycle, user-token resolution, HTTP routes, and request handling
Gmail client integrations/package/app/managers/gmail_client.py Gmail API requests, retrieval, search, attachment processing, token refresh, and mailbox operations
Additional Gmail handlers integrations/package/app/handlers/gmail_handlers.py Additional OAuth, inbox, search, and send handlers; registration and reachability require verification

The chat plugin constructs requests using INTEGRATIONS_SERVICE_URL and the /api/integrations-svc base path.

2. Supported capabilities

2.1 Read operations

The chat plugin defines the following read-oriented tools:

Tool Purpose
gmail_query Interprets natural-language requests and searches Gmail
search_emails Searches for matching email messages
read_inbox Retrieves inbox messages
get_inbox_stats Retrieves inbox statistics
get_email Retrieves an individual message
get_thread Retrieves a conversation thread
read_drafts Inspects existing drafts
list_attachments Lists message attachments
download_attachment Retrieves an attachment
list_labels Lists Gmail labels

The plugin includes parsing for sender and recipient filters, subjects, dates, categories, attachments, message states, and native Gmail search operators.

Actual results depend on query interpretation, Gmail API behavior, granted permissions, and the connected account.

2.2 Write and mailbox-modification operations

The source also defines operations that can change mailbox state or send messages.

Operation Tool or capability Effect Risk
Create a draft draft_email Creates a draft Write
Send an email send_email Sends a message External side effect
Reply reply_email Sends a reply External side effect
Forward forward_email Forwards a message External side effect
Modify labels modify_labels Adds or removes labels Write
Mark as read mark_read Removes unread state Write
Mark as unread mark_unread Adds unread state Write
Archive archive_email Removes the inbox label Write
Star star_email Adds or removes the starred label Write
Move to Trash trash_email Moves a message to Trash Destructive

The plugin metadata marks sending, drafting, replying, and forwarding as confirmation-requiring operations. Trash is categorized as destructive and requires confirmation. Some other modification tools do not declare confirmation requirements in their definitions.

Confirmation is not an authorization boundary

Confirmation prompts are not a substitute for enforcing a read-only policy. When strict read-only mode is required, write-capable operations must be denied even if a caller requests them or a confirmation flag is present.

Required policy: Disable or block every write-capable operation across tool registration, tool dispatch, and integration API routes. Verify the actual enforcement with negative tests before declaring compliance.

3. OAuth authentication

3.1 Authorization flow

The primary Gmail OAuth implementation is located in integrations/package/app/handlers/integration_handlers.py.

sequenceDiagram
    autonumber
    participant F as Frontend
    participant I as Integration service
    participant R as Redis
    participant G as Google OAuth
    participant U as User service

    F->>I: Start authorization with application JWT
    I->>I: Decode JWT and identify user
    I->>I: Generate state and PKCE verifier/challenge
    I->>R: Store state and verifier with TTL
    I-->>F: Redirect to Google authorization
    F->>G: Authorize requested scopes
    G-->>I: Callback with code and state
    I->>R: Retrieve and consume stored state
    I->>G: Exchange code using PKCE verifier
    G-->>I: OAuth tokens
    I->>I: Store token data server-side
    I->>U: Update connection status where supported
    I-->>F: Redirect with connection status

The documented implementation follows these steps:

  1. The frontend initiates Gmail authorization and supplies the application JWT.
  2. The integration handler decodes the JWT to identify the user.
  3. The handler generates a PKCE verifier, an S256 challenge, and a random state value.
  4. The verifier and user association are stored in Redis with a ten-minute expiration.
  5. The browser is redirected to Google's OAuth authorization page.
  6. Google returns an authorization code and state to the callback.
  7. The handler retrieves and deletes the stored state entry and exchanges the code using the PKCE verifier.
  8. The handler requires a refresh token and stores token data server-side.
  9. The user's Gmail connection is marked active where the connection update succeeds.
  10. The browser is redirected to the frontend with a connection-status indicator.

The success redirect is not intended to include token values. Verify this behavior for error redirects and every registered OAuth callback as well.

3.2 Requested OAuth scopes

Scope Purpose Read-only suitability
openid OpenID Connect identity Compatible
https://www.googleapis.com/auth/userinfo.email Read the user's email identity Compatible with identity lookup
https://www.googleapis.com/auth/gmail.readonly Read Gmail data Suitable for read-only access
https://www.googleapis.com/auth/gmail.compose Create and manage drafts and compose messages Broader than required for strict reading
https://www.googleapis.com/auth/gmail.modify Read and modify mailbox state Broader than required for strict reading

The primary implementation requests all five scopes. The compose and modify scopes are broader than a strict read-only integration requires.

Scope reduction requires migration planning

Reducing OAuth scopes may require renewed consent and reauthorization of existing connections. Verify the resulting granted scopes and token behavior rather than assuming a code change automatically narrows existing grants.

3.3 User-specific token resolution

The inspected integration handler:

  • Checks the user's Gmail connection status.
  • Retrieves stored token data for the requesting user.
  • Returns token information for downstream Gmail API calls.
  • Returns an unavailable-token result when the connection is inactive or token lookup fails.

The Gmail client can reuse a valid access token and request a replacement from Google's OAuth token endpoint when necessary. It also attempts to persist refreshed token data through the user service.

A global GMAIL_REFRESH_TOKEN fallback exists in some code paths. Until its use is verified and appropriately restricted, strict per-user isolation must not be assumed.

4. API reference

The routes below are documented from integrations/package/app/handlers/integration_handlers.py. Their effective prefix is /api/integrations-svc.

Routing caveat: The separate gmail_handlers.py module contains additional handlers. Confirm router registration and effective reachability in the deployed application before treating this table as an exhaustive API inventory.

4.1 OAuth and authentication

Method Endpoint Purpose
GET /api/integrations-svc/gmail/auth Starts Gmail OAuth
GET /api/integrations-svc/gmail/callback Handles the OAuth callback

4.2 Read endpoints

Method Endpoint Purpose
GET /api/integrations-svc/gmail/inbox Retrieves inbox messages
GET /api/integrations-svc/gmail/search Searches messages
GET /api/integrations-svc/gmail/stats Retrieves mailbox statistics
GET /api/integrations-svc/gmail/health Exposes a Gmail health endpoint
GET /api/integrations-svc/gmail/message/{message_id} Retrieves a message
GET /api/integrations-svc/gmail/thread/{thread_id} Retrieves a conversation
GET /api/integrations-svc/gmail/drafts Lists existing drafts
GET /api/integrations-svc/gmail/labels Lists Gmail labels
GET /api/integrations-svc/gmail/label/{label} Retrieves label statistics
GET /api/integrations-svc/gmail/message/{message_id}/attachments Lists message attachments
GET /api/integrations-svc/gmail/message/{message_id}/attachment/{attachment_id} Downloads an attachment

4.3 Write endpoints

These routes must be denied in strict read-only mode.

Method Endpoint Effect
POST /api/integrations-svc/gmail/send Sends an email
POST /api/integrations-svc/gmail/draft Creates a draft
POST /api/integrations-svc/gmail/reply Sends a reply
POST /api/integrations-svc/gmail/forward Forwards a message
POST /api/integrations-svc/gmail/labels/modify Modifies labels
POST /api/integrations-svc/gmail/message/{message_id}/read Marks a message as read
POST /api/integrations-svc/gmail/message/{message_id}/unread Marks a message as unread
POST /api/integrations-svc/gmail/message/{message_id}/archive Archives a message
POST /api/integrations-svc/gmail/message/{message_id}/trash Moves a message to Trash
POST /api/integrations-svc/gmail/message/{message_id}/star Stars or unstars a message

The existence of a route does not establish that it is appropriately authenticated, authorized, or protected by the read-only policy.

5. Configuration and credential handling

The following settings are referenced by the inspected implementation. Confirm their authoritative definitions, required values, and defaults against the repository's configuration and deployment files.

Setting Purpose
GMAIL_CLIENT_ID Google OAuth client identifier
GMAIL_CLIENT_SECRET OAuth client secret, where required by the client configuration
GMAIL_REDIRECT_URI Callback URI registered with Google
GMAIL_REFRESH_TOKEN Global refresh-token fallback in some code paths
GMAIL_SENDER_EMAIL Sender address used to construct outgoing messages
JWT_SECRET_KEY Application JWT decoding
JWT_ALGORITHM JWT algorithm configuration
INTERNAL_SECRET Authentication between trusted internal services
FRONTEND_URL Destination for OAuth callback redirects
INTEGRATIONS_SERVICE_URL Base URL used by the chat plugin
USER_SERVICE_URL User-service URL used to persist refreshed credentials

5.1 Security requirements

  • Never commit OAuth client secrets, access tokens, or refresh tokens to version control.
  • Keep production credentials in the approved secret-management system.
  • Never publish secrets in documentation, logs, screenshots, or issue reports.
  • Enforce user-specific credential lookup and authorization on every request.
  • Avoid shared global refresh tokens when strict per-user isolation is required.
  • Review requested OAuth scopes and remove unnecessary write permissions.
  • Redact sensitive provider responses and prevent email content from leaking into logs.
  • Restrict internal-service endpoints to authenticated, authorized callers.

5.2 Example environment configuration

The following is a template, not a complete deployment configuration. Supply values through the approved secrets and environment-management mechanism.

GMAIL_CLIENT_ID=<google-oauth-client-id>
GMAIL_CLIENT_SECRET=<managed-secret>
GMAIL_REDIRECT_URI=<registered-callback-uri>

JWT_SECRET_KEY=<managed-application-secret>
JWT_ALGORITHM=<configured-jwt-algorithm>
INTERNAL_SECRET=<managed-internal-service-secret>

FRONTEND_URL=<frontend-base-url>
INTEGRATIONS_SERVICE_URL=<integration-service-base-url>
USER_SERVICE_URL=<user-service-base-url>

Do not place actual credentials in the documentation. The global refresh-token fallback and sender-address settings are intentionally omitted from this baseline template because their necessity and intended production use must first be verified.

6. Query processing and result handling

The email plugin translates conversational requests into Gmail search queries instead of passing every natural-language request directly to the provider.

Query category Examples of supported intent
Sender and recipient Messages from a person or sent to a particular address
Subject and phrases Subject matches and exact-phrase searches
Date range Recent messages or messages from an explicit period
Categories and labels Category-specific or label-specific searches
Message state Read, unread, or starred messages
Attachments Messages with attachments or common file types
Conversations Threads and related messages
Aggregation Message counts and inbox statistics
Native query syntax Gmail search operators

The plugin also preserves message and thread references in response-processing logic so later conversational requests can refer to previously retrieved emails.

These are documented implementation capabilities, not a guarantee that every natural-language request will be interpreted correctly. Regression tests should cover ambiguous phrasing, empty results, date boundaries, and provider-specific query behavior.

7. Error handling and observability

The inspected implementation uses HTTP status checks, exceptions, and logging around Gmail API requests and OAuth processing. The chat plugin also handles integration-service errors and includes a health-check method that requests a small inbox result.

Failure category Recommended verification
Missing OAuth configuration Fail safely without exposing secret values
Invalid, expired, or revoked credentials Return an appropriate error and handle reconnection
OAuth callback or token-exchange failure Validate state handling and redact provider responses
Missing or inactive connection Deny access without falling back to another user's credentials
Gmail API authorization failure Distinguish permission failures from general upstream errors
Network timeout or upstream failure Verify timeout behavior and bounded retries
Attachment retrieval failure Validate ownership, identifiers, and error responses
Token persistence failure Test refresh success followed by persistence failure
Invalid identifiers or query parameters Reject malformed inputs and out-of-range values

Logging requirements: Do not expose access tokens, refresh tokens, authorization codes, message bodies, or unnecessary provider response details. Review existing logging paths before production use.

A successful HTTP response or a health endpoint response alone does not establish full integration readiness.

8. Security findings and remediation priorities

The following findings are based on source inspection. They are not claims that fixes have been implemented or that tests have passed.

ID Finding Required action Priority
GMAIL-01 Write-capable tools and endpoints are present Enforce read-only restrictions at registration, dispatch, and API boundaries Critical
GMAIL-02 OAuth requests include compose and modify scopes Establish the minimum scope set and plan reauthorization High
GMAIL-03 Some paths use a global refresh-token fallback Verify user isolation and eliminate unsafe cross-account fallback Critical
GMAIL-04 A separate gmail_handlers.py contains additional handlers Audit route registration and remove or secure duplicate paths High
GMAIL-05 OAuth failure paths may log provider response text Redact sensitive response details and audit logs High
GMAIL-06 Some request parameters need boundary validation Test limits, malformed inputs, and pagination High
GMAIL-07 Refreshed-token persistence can fail after refresh Define safe recovery and concurrent-refresh behavior High
GMAIL-08 OAuth state and PKCE depend on temporary storage Test expiration, replay, invalid callbacks, and multi-instance behavior High
GMAIL-09 Authentication spans the plugin and integration service Test user headers, internal secrets, and authorization boundaries Critical
GMAIL-10 Health checks may not establish complete readiness Test disconnected accounts, expired tokens, and dependency failures Medium
GMAIL-11 Natural-language parsing has multiple patterns and fallbacks Build a representative regression suite Medium
GMAIL-12 Source inspection does not establish end-to-end reliability Run controlled integration tests before release High

Priorities indicate suggested remediation order, not a completed security assessment or a formal risk acceptance.

9. Verification checklist

Use this checklist during implementation review and release validation. Mark items complete only when supported by test evidence.

OAuth and credential security

  • OAuth consent and callback work with a dedicated test account.
  • PKCE state expires and can be consumed only once.
  • Invalid, missing, expired, and replayed state values fail safely.
  • Credentials remain server-side and never appear in frontend responses.
  • User A cannot retrieve User B's messages, tokens, or connection data.
  • Missing connections and invalid internal-service credentials fail closed.
  • Token refresh, persistence failures, and concurrent refreshes are tested.
  • OAuth redirects and logs do not expose secrets or authorization codes.

Read-only enforcement

  • Every write-capable tool is disabled or rejected.
  • Direct requests to every write endpoint are denied.
  • Read-only enforcement cannot be bypassed by supplying confirmation metadata.
  • No alternate or duplicate route bypasses the policy.
  • OAuth scopes match the approved read-only behavior.
  • Negative tests confirm that no mailbox state or message is changed.

Functional and operational validation

  • Inbox, search, message, thread, and label retrieval return expected results.
  • Attachment listing and downloads enforce user authorization.
  • Result limits, identifiers, and query parameters are validated.
  • Natural-language search regression tests cover dates, senders, phrases, attachments, ambiguity, and empty results.
  • Error responses and logs do not expose secrets or unnecessary message content.
  • Health checks reflect the readiness criteria adopted for deployment.
  • End-to-end tests pass against the intended deployment configuration.

Release acceptance criteria

Approve the integration for strict read-only use only after the write paths are demonstrably blocked, per-user isolation is tested, OAuth scopes are reviewed, and the relevant end-to-end tests pass. Documentation completion alone is not sufficient evidence.

10. Source of truth and change management

The source repository remains authoritative for implementation behavior. Review this page whenever the Gmail plugin, OAuth scopes, token storage, integration routes, configuration, or read-only policy changes.

Keep the following distinctions explicit during future updates:

  • Implemented: Supported by source inspection.
  • Verified: Confirmed by reproducible tests or deployment evidence.
  • Required: A security, operational, or product acceptance criterion that may not yet be implemented.

Do not document a capability as a security guarantee until its enforcement has been verified and tested.