TL;DR

Gmail-connected apps built with AI coding tools fail in six predictable places. Check these before launch, in this order:

  1. Scopes: ask for the narrowest Gmail scope, not full access
  2. Token storage: refresh tokens encrypted, server-side, per user, revocable
  3. Per-user isolation: one user can never read another user’s messages, even through a bug
  4. Google verification and CASA: without it you are capped at 100 test users and 7-day tokens
  5. Watch renewals: push notifications expire after 7 days; renew and reconcile
  6. Deletion and data policy: delete means delete, including Google’s Limited Use rules

If you built an app on Gmail with Cursor, Claude Code, Lovable, Replit, or Bolt, it probably works. That is not the question before launch. The question is whether it keeps working with real users, real inboxes, and Google’s reviewers watching. Here is what a senior architect checks first, with the numbers that matter.

1. Scopes: the AI asked for more than you need

Gmail’s API has a ladder of OAuth scopes. gmail.readonly reads. gmail.send sends. gmail.modify labels and archives. https://mail.google.com/ is full access, including permanent deletion. AI coding tools tend to request full access because every feature works on the first try.

Three problems follow. Users see a scarier consent screen and drop off. Google’s verification review asks you to justify every scope, and “the AI picked it” is not a justification. And a breach of a full-access token is a breach of the whole mailbox.

The check: open your OAuth client configuration and your code’s scope list. If mail.google.com is there and you do not delete messages, remove it. Expect to re-verify after a scope change.

2. Token storage: where the refresh tokens actually live

A Gmail refresh token is a standing key to someone’s inbox. The pattern in AI-built apps, seen repeatedly: the token is written to a database column in plain text, sometimes logged on every request, occasionally shipped to the browser so the frontend can “call Gmail directly.”

What has to hold:

  • Tokens are stored server-side only, encrypted at rest with a key from a KMS or vault, not a constant in the code.
  • Each token is bound to exactly one user record; the lookup is by the authenticated session, never by a client-supplied user id.
  • Logs redact tokens and message bodies.
  • Deleting the account revokes the token at Google (oauth2.revoke) and destroys the stored copy.

The check: search the repo and the database schema for refresh_token. Trace every read of that column. If any path returns it to the client or writes it to a log, that is finding number one of your teardown.

3. Per-user isolation: the bug that leaks someone else’s inbox

Every Gmail-connected app has a place where it decides whose token to use. In AI-built code that decision is often made from a parameter in the request (?userId=), from a cached “current user” variable that survives across requests, or from a background job that iterates users and reuses one client object.

This is the failure mode that turns a bug into a breach: user A’s sync job runs with user B’s token, or a shared client retains the last user’s credentials. It is invisible in single-user testing.

The check: find every construction of the Gmail client. Confirm it is built from the token of the authenticated user in that request or that job, and destroyed after. Then write the one test that matters: two users, two inboxes, assert that no call for user A ever carries user B’s token.

4. Google verification and the CASA assessment

Until your OAuth consent screen is published and verified, the project stays in Testing mode: a maximum of 100 test users, refresh tokens that expire after 7 days, and an “unverified app” screen for everyone. Founders hit this the week after launch, when the first cohort’s connections silently die.

Any restricted Gmail scope (read, modify, send) requires more than the standard brand verification: an independent CASA (Cloud Application Security Assessment) by a Google-authorized assessor, renewed every year. Plan for weeks of calendar time and an external cost, and expect the assessor to ask about the exact things in sections 2 and 3.

The check: in Google Cloud Console, look at the OAuth consent screen’s publishing status and verification status. If it says Testing, your launch has a 100-user ceiling today.

5. Watch renewals: push notifications expire after 7 days

If the app reacts to new mail, it uses users.watch() to get push notifications through Pub/Sub. That subscription expires after 7 days. Production integrations renew it on a schedule and, after any gap, catch up with history.list from the last known historyId.

AI-generated code creates the watch once, during setup, and never again. The symptom: the app works in the demo, then goes quiet for every user about a week after they connected.

The check: search for watch(. If there is no scheduled renewal and no reconciliation on historyId, the integration is a demo, not a product.

6. Deletion, retention, and Google’s Limited Use rules

Gmail data falls under Google’s API Services User Data Policy, including the Limited Use requirements: use the data only to provide the user-facing feature, do not sell it, do not use it for ads, and do not let humans read it except in narrow cases. Your privacy policy has to say this, and the app has to do it.

AI-built apps commonly cache message bodies “for performance,” keep them after the user disconnects, and feed them to a third-party model without telling the user.

The check: disconnect a test account and look at the database. Anything left is a policy problem and, for employment or health data, a legal one.

What “ready” looks like

A Gmail-connected app is launch-ready when: the scope list is minimal and justified; tokens are encrypted, server-side, per user, and revoked on deletion; the two-user isolation test passes; the consent screen is verified (with the CASA assessment scheduled if the scopes are restricted); watches renew on a schedule; and disconnect leaves nothing behind.

None of this requires a rewrite. In most AI-built apps it is a fixed-scope hardening pass of one to two weeks, done once, with the trail left behind: the isolation test, the renewal job, the runbook for the day Google emails you about your assessment.

If you want senior eyes on your actual code first, that is what the free teardown is: three findings and a verdict, recorded, within 72 hours.