Skip to content

fix: request Drive scope in gwcli configure#48

Merged
wesnick merged 1 commit into
mainfrom
fix/configure-missing-drive-scope
May 20, 2026
Merged

fix: request Drive scope in gwcli configure#48
wesnick merged 1 commit into
mainfrom
fix/configure-missing-drive-scope

Conversation

@wesnick

@wesnick wesnick commented May 19, 2026

Copy link
Copy Markdown
Owner

Problem

gwcli configure never asks for the Drive scope, so every drive * /
artifacts download command fails with insufficient scope on a freshly
configured account — and there is no consent path that requests Drive at all.

The live consent path is:

gwcli configurerunConfigureConfigureAuthNewAuthenticator → builds the consent URL from authScopes (oauth.go).

authScopes listed gmail.modify, gmail.settings.basic, gmail.labels, tasks, calendar — no Drive.

Why it was hard to see

Three divergent scope definitions existed; the two that did include Drive were unreachable dead code:

Location Scopes Live?
authScopes (oauth.go) gmail×3, tasks, calendar — no drive ✅ the one that runs
scope const (connection.go) gmail×3, drive ❌ only used by dead auth()
inline list in oauth2Config gmail×3, drive ❌ cosmetic at runtime, divergent

The reasoning in the old authScopes comment ("Drive requested separately because DWD token exchange is all-or-nothing") is correct for service accounts but was wrongly applied to the installed-app OAuth flow, where every scope must be bundled onto the one consent screen (Google won't add scopes to an already-issued token).

Changes

  • Add drive.DriveScope to authScopes — the actual fix; comment rewritten to explain the installed-app vs. service-account distinction. The service-account DWD path still requests Drive separately and is unaffected.
  • oauth2Config now reuses authScopes instead of its own hardcoded list — single source of truth, can't silently diverge again.
  • Delete the dead OAuth-configure cluster (configure.go: Configure/auth/makeConfig/readConf/readLine; the scope and accessType consts) that the real ConfigureAuth flow never invokes.
  • TestNewAuthenticatorScopes now asserts Drive is requested.

Migration

Existing OAuth users must re-run gwcli configure to re-consent — Google does not grant new scopes to an already-issued token.json. (This is already documented in CLAUDE.md/README.)

Testing

go build ./..., go vet ./..., go test ./... — all pass.

🤖 Generated with Claude Code

The live consent path (`gwcli configure` -> ConfigureAuth ->
NewAuthenticator) built the OAuth consent URL from `authScopes`
(oauth.go), which omitted `https://www.googleapis.com/auth/drive`.
A freshly-configured OAuth token therefore never carried the Drive
scope, so every `drive *` / `artifacts download` command failed with
insufficient scope, and there was no consent path that requested Drive
at all.

The codebase had three divergent scope definitions, which masked the
bug (two of them *did* list Drive but were unreachable dead code):

- `authScopes` (oauth.go)            - the only one that runs; no Drive
- `scope` const (connection.go)      - only used by dead `auth()`
- inline list in `oauth2Config`      - cosmetic at runtime; divergent

Fix and consolidate to a single source of truth:

- Add `drive.DriveScope` to `authScopes` (the actual fix) and rewrite
  the comment to explain installed-app OAuth is not all-or-nothing but
  Google won't add scopes to an already-issued token, so everything
  must be bundled on the consent screen. The service-account DWD path
  still requests Drive separately and is unaffected.
- `oauth2Config` now reuses `authScopes` instead of its own hardcoded
  list, so the lists can't silently diverge again.
- Delete the dead OAuth-configure cluster (configure.go: Configure /
  auth / makeConfig / readConf / readLine, the `scope` and `accessType`
  consts) that the real `ConfigureAuth` flow never invokes.
- Update TestNewAuthenticatorScopes to assert Drive is requested.

Existing OAuth users must re-run `gwcli configure` to re-consent
(Google does not grant new scopes to an already-issued token.json).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wesnick
wesnick merged commit 98a6931 into main May 20, 2026
1 check passed
@wesnick
wesnick deleted the fix/configure-missing-drive-scope branch May 20, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant