When using the gws CLI with an OAuth desktop app flow, Drive API calls fail with a 403 Forbidden error for users who are not IAM members of the GCP project specified in client_secret.json. Gmail and Calendar API calls succeed for the same user with the same credentials.
Error:
Caller does not have required permission to use project [project-id].
Grant the caller the roles/serviceusage.serviceUsageConsumer role,
or a custom role with the serviceusage.services.use permission.
Root cause:
The CLI reads project_id from client_secret.json and sends it as the x-goog-user-project header on API requests. This triggers a GCP IAM check requiring the caller to have serviceusage.services.use on the specified project. For users who are not project members (common when distributing an OAuth app org-wide), this check fails.
Why this is unexpected:
Google Workspace APIs are designed to attribute quota to the project that owns the OAuth client ID automatically via the token. Explicitly sending x-goog-user-project is unnecessary for Workspace API calls and introduces an IAM requirement that doesn't need to exist. Gmail and Calendar appear to handle this more leniently, but Drive strictly enforces it, resulting in inconsistent behavior across Workspace APIs.
Expected behavior:
All Workspace API calls should succeed for any authenticated user without requiring IAM roles on the GCP project, since quota attribution happens automatically through the OAuth client ID.
Steps to reproduce:
- Create an OAuth desktop app client in a GCP project
- Distribute
client_secret.json (with project_id field) to a user who has no IAM roles on the project
- User authenticates:
gws auth login -s drive,gmail,calendar
- User runs a Gmail command — succeeds
- User runs a Calendar command — succeeds
- User runs a Drive command — fails with 403
Workaround:
Grant roles/serviceusage.serviceUsageConsumer to all users on the GCP project.
Suggested fix:
Do not send the x-goog-user-project header when using OAuth desktop app credentials for Workspace API calls, or make it opt-in rather than automatic.
Environment:
- gws CLI version: 0.22.5
- OS: macOS (Apple Silicon)
- Auth method: OAuth desktop app flow
When using the gws CLI with an OAuth desktop app flow, Drive API calls fail with a
403 Forbiddenerror for users who are not IAM members of the GCP project specified inclient_secret.json. Gmail and Calendar API calls succeed for the same user with the same credentials.Error:
Root cause:
The CLI reads
project_idfromclient_secret.jsonand sends it as thex-goog-user-projectheader on API requests. This triggers a GCP IAM check requiring the caller to haveserviceusage.services.useon the specified project. For users who are not project members (common when distributing an OAuth app org-wide), this check fails.Why this is unexpected:
Google Workspace APIs are designed to attribute quota to the project that owns the OAuth client ID automatically via the token. Explicitly sending
x-goog-user-projectis unnecessary for Workspace API calls and introduces an IAM requirement that doesn't need to exist. Gmail and Calendar appear to handle this more leniently, but Drive strictly enforces it, resulting in inconsistent behavior across Workspace APIs.Expected behavior:
All Workspace API calls should succeed for any authenticated user without requiring IAM roles on the GCP project, since quota attribution happens automatically through the OAuth client ID.
Steps to reproduce:
client_secret.json(withproject_idfield) to a user who has no IAM roles on the projectgws auth login -s drive,gmail,calendarWorkaround:
Grant
roles/serviceusage.serviceUsageConsumerto all users on the GCP project.Suggested fix:
Do not send the
x-goog-user-projectheader when using OAuth desktop app credentials for Workspace API calls, or make it opt-in rather than automatic.Environment: