fix(auth): retry stale scoped token once after 403#895
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 189b8ab0be
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Codex review: needs maintainer review before merge. Reviewed July 1, 2026, 9:53 AM ET / 13:53 UTC. Summary Reproducibility: Do we have a high-confidence way to reproduce the issue? No: source and tests model the retry path, and authenticated smoke was reported green, but the real intermittent first-response Google 403 cannot be safely forced on demand. Review metrics: 2 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: A maintainer should either explicitly waive the unforceable live-provider branch after reviewing the focused tests and smoke proof, or wait for a natural redacted reproduction before merging the auth retry behavior. Do we have a high-confidence way to reproduce the issue? Do we have a high-confidence way to reproduce the issue? No: source and tests model the retry path, and authenticated smoke was reported green, but the real intermittent first-response Google 403 cannot be safely forced on demand. Is this the best way to solve the issue? Is this the best way to solve the issue? Unclear pending maintainer sign-off: a narrow stored-user-OAuth-only one-time replay is plausible and now covered, but accepting mock/harness proof for the provider branch is an auth-provider product and risk decision. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 621757c686ee. Label changesLabel changes:
Label justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
189b8ab to
2b213d8
Compare
842b5b0 to
b4d8e96
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b4d8e96f14
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Maintainer closeout on exact head
The single remaining gate is unchanged: Google's intermittent first-response insufficient-scope 403 did not occur naturally and cannot be safely induced against the real provider. Please explicitly waive that item-specific live-provider branch requirement to authorize merge, or provide a redacted natural reproduction. I have left the PR unmerged. |
|
Addressed the later ClawSweeper P2 finding on exact head
The one remaining gate is unchanged: Google's intermittent first-response under-scope 403 cannot be safely forced against the live provider. Please grant the item-specific live-proof waiver before merge, or provide a naturally observed redacted reproduction. I am leaving the clean, green PR unmerged pending that decision. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 070af73207
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if err := t.RefreshAuth(req.Context()); err != nil { | ||
| return nil, fmt.Errorf("refresh auth after insufficient scopes response: %w", err) |
There was a problem hiding this comment.
Return the original 403 when forced refresh fails
When a stored grant is genuinely missing the requested scope, the first Google API call returns the useful insufficient-scope 403, but the forced refresh can then fail at the token endpoint with invalid_scope; this path discards the original response and returns only the refresh error. Callers such as wrapYouTubeForceSSLError look for the original insufficientPermissions / insufficient authentication scopes text to show the gog auth add ... --force-consent hint, so under-scoped grants now lose that actionable guidance. Preserve and return the original 403 when RefreshAuth fails, or translate that failure into the same reauth error.
Useful? React with 👍 / 👎.
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Addressed the fresh ClawSweeper P2 on exact head
The only remaining gate is the explicit item-specific waiver for the intermittent live-provider first-response 403, which cannot be safely induced. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Summary
insufficientPermissionsand singularInsufficient Permissionresponse variantsCloses #889.
Supersedes #890 after maintainer hardening while retaining its original implementation commit.
Root cause
Since
1531013e, the CLI persists and reuses a still-valid access token.golang.org/x/oauth2returns that cached token without contacting the token endpoint until expiry. If Google transiently rejects that token as under-scoped, the current retry transport treats the first non-429 4xx as terminal. The candidate now discards the rejected cached access token, mints through the stored refresh token, persists returned metadata, and replays once.Final exact-head proof
Exact head:
ac67db3a4dc4124d7659f96fc1152d0ca421bb32make civ0.31.1-18-gac67db3a; SHA-256c03f2e3cff64f75bf661f07c087a3df316667b149b7e5b1f37abb6125016e1a4Review repairs
insufficientPermissionsreason and singular permission message while leaving ordinary permission denials untouchedmain, preserving the youtube videos list: add opt-in --parts all without changing defaults #871 changelog entryLive-proof caveat
Google's intermittent first-response 403 cannot be safely or deterministically forced on the real provider. The exact recovery branch is covered by replay, refresh, concurrency, ordinary-403, non-replayable-body, detector-variant, and response-preservation tests; final-head authenticated Contacts and Calendar smoke is green. Merge should wait for an item-specific waiver of the unforceable provider-403 proof requirement, or for a naturally observed redacted reproduction.