Skip to content

Bug: Windows — API calls fail with insufficient scopes despite valid refresh token #489

@paul-cimento

Description

@paul-cimento

Environment

  • gws version: latest from npm (npm install -g @googleworkspace/cli)
  • OS: Windows 11
  • Shell: PowerShell 5.1
  • Keyring backend: keyring (default)
  • Google Workspace account: yes (Workspace domain)
  • OAuth app status: External, testing mode

Steps to Reproduce

  1. Run gws auth setup — completes successfully
  2. Run gws auth login -s calendar — completes successfully, reports https://www.googleapis.com/auth/calendar in saved scopes
  3. Run gws calendar +agenda

Expected

Calendar agenda is returned.

Actual

{
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
        "metadata": {
          "service": "calendar-json.googleapis.com",
          "method": "calendar.v3.CalendarList.List"
        }
      }
    ]
  }
}

Diagnosis

The refresh token is valid and has the correct scopes. Manually exchanging it via https://oauth2.googleapis.com/token confirms the token includes https://www.googleapis.com/auth/calendar:

# Exchange refresh token manually
$body = @{
    client_id     = "<REDACTED>"
    client_secret = "<REDACTED>"
    refresh_token = "<REDACTED>"
    grant_type    = "refresh_token"
}
$response = Invoke-RestMethod -Method Post -Uri "https://oauth2.googleapis.com/token" -Body $body
$response.scope
# Output includes: https://www.googleapis.com/auth/calendar openid https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/userinfo.email

Setting the access token directly via env var works:

$env:GOOGLE_WORKSPACE_CLI_TOKEN = $response.access_token
gws calendar +agenda
# Returns calendar data successfully

This confirms gws is not correctly using the stored refresh token to obtain access tokens. The issue persists even after:

  • Deleting credentials.enc
  • Setting GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE to a valid plaintext JSON credentials file (created from gws auth export --unmasked)
  • Setting GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file

In all cases, the API call still fails with "insufficient scopes", even though the underlying refresh token has the correct scopes.

The same behavior occurs across all Workspace APIs tested (Calendar, Drive, Gmail), not just Calendar.

Possibly Related

Workaround

Manually refresh the access token and set GOOGLE_WORKSPACE_CLI_TOKEN:

$body = @{
    client_id     = "<from gws auth export>"
    client_secret = "<from gws auth export>"
    refresh_token = "<from gws auth export>"
    grant_type    = "refresh_token"
}
$response = Invoke-RestMethod -Method Post -Uri "https://oauth2.googleapis.com/token" -Body $body
$env:GOOGLE_WORKSPACE_CLI_TOKEN = $response.access_token
# All gws commands now work for ~1 hour until the access token expires

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions