#876·cli

gws auth login can silently leave a stale/split token cache, causing 403 insufficient authentication scopes after re-auth

Author: kbroughtonCreated Jul 15, 2026Updated Sep 11, 2026

Summary

After re-authenticating (gws auth login -s drive,docs), gws continued returning 403 insufficient authentication scopes on every Drive API call, while Gmail-scoped calls succeeded fine throughout. The login command's own output correctly listed https://www.googleapis.com/auth/drive as a granted scope, and ~/.config/gws/credentials.enc had a fresh timestamp — but the actual Drive API calls kept failing as if that scope had never been granted.

Environment

  • gws version: 0.11.1 (@googleworkspace/cli)
  • macOS 15.7.3 (Build 24G419)
  • Auth method: OAuth2, installed/desktop client (redirect_uris: ["http://localhost"])
  • Keyring backend: keyring

What was ruled out before finding the real cause

Extensive troubleshooting confirmed this was not caused by any of the following (each checked directly):

  • OAuth consent screen scope configuration (Drive API confirmed ENABLED via gcloud services list)
  • OAuth consent screen test users list (account confirmed present)
  • A stray local process holding a port from a previous gws auth login invocation (found and killed one, no change)
  • A full OS reboot (no change — rules out any in-memory/process-level caching)
  • client_secret.json validity (if this were invalid, login itself would fail with invalid_client, not succeed and then fail on API calls — and other-scoped calls, e.g. Gmail, worked fine throughout)

Multiple full gws auth login -s drive,docs re-runs across this window, including after switching to a different Google account and back, did not resolve the issue.

Root cause (as best diagnosed)

~/.config/gws/ contains two separate local token/credential stores:

  • credentials.enc (encrypted, gets a fresh timestamp on every gws auth login)
  • token_cache.json (binary — not actually JSON despite the extension/name; failed UTF-8 decode when inspected)

A normal gws auth login re-auth appears to refresh credentials.enc but not fully invalidate/replace whatever state token_cache.json holds (or vice versa — the exact read/write interaction between the two wasn't fully traced from the outside). The practical symptom: the CLI looks like it completed a fresh login with the requested scope, but the token actually used for API calls doesn't carry that scope.

Workaround that fixed it

Manually deleting the cached credential/token state (while preserving the app config) and then doing a completely fresh login resolved the issue immediately:

bash
rm ~/.config/gws/credentials.enc ~/.config/gws/token_cache.json
rm -rf ~/.config/gws/cache/*   # cached API discovery docs, unrelated to auth but safe to clear too
gws auth login -s drive,docs

(client_secret.json and .encryption_key were left untouched — those are the app identity/encryption key, not per-session state.)

Immediately after this, gws drive files list succeeded and returned real results.

Suggested fix

gws auth login (or a new --fresh/--clear-cache flag) should fully clear all local token/credential state before starting a new interactive login, rather than leaving a possibly-stale secondary cache (token_cache.json) in place alongside a freshly-written credentials.enc. Right now the only way to force a truly clean re-auth is to know to manually delete files inside ~/.config/gws/ — there's no documented or CLI-exposed way to do this.

Happy to provide more detail if useful — this took a couple hours of systematic elimination to track down, so hopefully this saves someone else the trouble.