Google OAuth verification with Gmail node: how do you pass verification when GmailOAuth2Api forces 6 scopes?

Hi everyone,

I’m building a self-hosted AI email assistant with n8n for small businesses and I’m currently preparing for Google OAuth verification.

The workflow:

  • Reads unread Gmail messages
  • Filters automated emails
  • Sends the content to Claude
  • Creates Gmail drafts
  • Marks the message as read only after successful processing
  • Sends an execution summary

The application never permanently deletes emails.

What I found

After investigating, I discovered that the native Gmail OAuth2 API credential has its scopes hardcoded.

It always requests:

  • gmail.labels
  • gmail.addons.current.action.compose
  • gmail.addons.current.message.action
  • mail.google.com
  • gmail.modify
  • gmail.compose

The Scope property is hidden, so there is no way to customize it from the UI.

I also found community discussions showing that simply restricting scopes in Google Cloud causes OAuth authorization to fail with HTTP 403 because the Gmail credential still requests the full hardcoded scope list.

There is also an open feature request asking for the Gmail node to support the generic Google OAuth credential instead of the fixed Gmail credential.

My question

Has anyone here actually completed Google’s OAuth verification while keeping the native Gmail node?

If yes:

  • Did Google accept the default hardcoded scopes?
  • Did you have to justify mail.google.com?
  • Did Google request any changes?

Or did you end up replacing the Gmail nodes with HTTP Request nodes using a generic Google OAuth2 credential and the Gmail REST API?

I’m not looking for theoretical advice—I would really like feedback from someone who has successfully completed Google’s verification process with a production n8n application.

Thanks!

e share your workflow

(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version: “localhost”
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app): DOCKER
  • Operating system:

Hi @Jidenkaes
The blocker isn’t the six scopes as a group, it’s that the native Gmail node hardcodes https://mail.google.com/, a restricted scope (full access, including permanent delete). That single scope is what drops you onto Google’s restricted-scope track: the annual third-party security assessment, plus reviewers rejecting a full-access request from an app that only reads, drafts, and marks as read.

Your whole workflow (read unread, create drafts, remove the UNREAD label) fits inside one scope, gmail.modify. Google classifies it as sensitive rather than restricted, specifically because it can’t permanently delete mail, which yours already never does. That keeps you on the lighter sensitive-scope verification instead of the restricted one, and gives you a clean least-privilege justification.

The Gmail node won’t let you trim its scopes, so replace those nodes with HTTP Request nodes hitting the Gmail REST API, authenticated with a generic Google OAuth2 API credential where you enter the scope yourself:

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

Thanks, that’s very helpful. Just to clarify: have you personally completed Google’s OAuth verification using the HTTP Request + generic Google OAuth2 approach, or is this the architecture you would recommend? I’m trying to determine whether someone has successfully passed Google’s review with this setup.