bug: Interactive TUI unconditionally injects cloud-platform scope, breaking org-restricted accounts

Open Beginner friendly
#562 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
rust

Research direction

Read the scope-selection logic around line 860 in src/auth_commands.rs, then run the provided gws auth login reproductions with and without the TUI. Done means the TUI respects the user's selected scopes and cloud-platform appears only when explicitly requested, via the TUI, --full, or --scopes.

Written by the indexing model from the issue text.

Description

Problem

The interactive TUI scope picker in gws auth login unconditionally injects the cloud-platform scope after selection, regardless of what the user chose. This causes admin_policy_enforced errors for users in Google Workspace organizations that block the cloud-platform scope.

Root Cause

In src/auth_commands.rs, line ~860:

// Always include cloud-platform scope
if !selected.contains(&PLATFORM_SCOPE.to_string()) {
    selected.push(PLATFORM_SCOPE.to_string());
}

This runs after every TUI selection, forcing cloud-platform into the scope list even when the user explicitly chose only basic services.

Contradiction with DEFAULT_SCOPES

The code comments on lines 56-62 explicitly acknowledge that cloud-platform is restricted and was intentionally removed from DEFAULT_SCOPES:

/// Previously this included `pubsub` and `cloud-platform`, which Google marks
/// as *restricted* and blocks for unverified apps, causing `Error 403:
/// restricted_client`.  Use `--scopes` to add those scopes explicitly when you
/// have a verified app or a GCP project with the APIs enabled and approved.
pub const DEFAULT_SCOPES: &[&str] = MINIMAL_SCOPES;

Yet the TUI path contradicts this design by force-injecting the scope that was deliberately excluded.

Reproduction

# This works (no TUI, no cloud-platform injected):
echo "" | gws auth login

# This fails (TUI injects cloud-platform):
gws auth login

# This also fails (TUI still opens even with -s):
gws auth login -s drive,gmail,calendar,sheets,docs,slides
Error
Error 400: admin_policy_enforced

The generated OAuth URL contains cloud-platform even when only basic services (drive, gmail, calendar) are selected in the TUI.

Expected Behavior

  • The TUI should NOT force-inject cloud-platform — it should respect the user's selection
  • cloud-platform should only be included when the user explicitly selects it in the TUI, uses --full, or adds it via --scopes
  • The TUI behavior should be consistent with DEFAULT_SCOPES (which excludes cloud-platform)

Suggested Fix

Remove or conditionalize the forced injection at line ~860:

-            // Always include cloud-platform scope
-            if !selected.contains(&PLATFORM_SCOPE.to_string()) {
-                selected.push(PLATFORM_SCOPE.to_string());
-            }

If cloud-platform needs to remain available, it should be a selectable option in the TUI rather than being silently injected.

Workaround

Bypass the TUI by piping empty input:

echo "" | gws auth login

Environment

  • gws v0.18.0 (homebrew)
  • Managed Google Workspace account
  • macOS
Dominant language
Rust
Stars
31.1k
Forks
1.8k
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from googleworkspace/cli

All issues in googleworkspace/cli

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.