fix(git-auth): fall back to still-valid token on near-expiry refresh failure - #1213
detail-app[bot] wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Stale comment
Not approved: this is a functional
pb auth git/ credential-exchange change, not a small fixup, so it still needs human review. Cursor Bugbot and Cursor Security Agent both completed with no findings that need attention; no reviewers were assigned.Sent by Cursor Approval Agent: Pull Request Router and Approver
926f8c6 to
63c31ad
Compare
There was a problem hiding this comment.
Stale comment
Not approved: this remains a functional
pb auth git/ token-refresh fallback change, not a small fixup, so it still needs human review. Cursor Bugbot completed with no findings that need attention; Cursor Security Agent was not running on this update. No reviewers were assigned.Sent by Cursor Approval Agent: Pull Request Router and Approver
63c31ad to
ac8bdaf
Compare
There was a problem hiding this comment.
Devin Review found 1 new potential issue.
1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
There was a problem hiding this comment.
🟡 Service-account fallback is bypassed
With 31–60 seconds remaining, saved_token renews a service-account token and propagates any failure. The Git exchange never receives its still-valid token.
(Refers to this code)
Prompt for agents
Extend the Git-only refresh fallback to saved service-account authentication. In crates/pcb-diode-api/src/auth.rs, get_valid_token_with_sources returns from service_account::saved_token before the human-token fallback logic. AccessToken::is_valid uses a 60-second margin, so a renewal failure with 31–60 seconds remaining rejects a token that still covers the Git exchange's 30-second timeout. Preserve the existing behavior for normal callers and environment credentials, while allowing the Git-specific helper to reuse the saved service-account token only when its post-failure remaining lifetime exceeds the requested fallback lifetime. Add coverage for failed and successful service-account renewal around this window.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
The observation is correct, but this saved-service-account behavior also exists on current origin/main. This PR fixes the human OAuth refresh-token failure path; it leaves service-account renewal and other callers unchanged. Extending fallback into saved_token would change a separate client-credentials path that re-reads credentials under a lock, so it is not included as a regression fix here. This thread remains open for a human scope/follow-up decision; no service-account behavior change is proposed in this PR.
There was a problem hiding this comment.
Stale comment
Not approved: this remains a functional
pb auth git/ token-refresh fallback change, not a small fixup, so it still needs human review. Cursor Bugbot completed with no findings that need attention; Cursor Security Agent was not running on this update. No reviewers were assigned.Sent by Cursor Approval Agent: Pull Request Router and Approver
ac8bdaf to
decaef5
Compare
There was a problem hiding this comment.
Stale comment
Not approved: this remains a functional
pb auth git/ token-refresh fallback change, not a small fixup, so it still needs human review. Cursor Bugbot completed with no findings that need attention; Cursor Security Agent was not running on this update. No reviewers were assigned.Sent by Cursor Approval Agent: Pull Request Router and Approver
decaef5 to
1e86c22
Compare
There was a problem hiding this comment.
Not approved: this remains a functional pb auth git / token-refresh fallback change, not a small fixup, so it still needs human review. Cursor Bugbot completed with no findings that need attention; Cursor Security Agent was not running on this update. No reviewers were assigned.
Sent by Cursor Approval Agent: Pull Request Router and Approver


Keep Git authentication working after token refresh fails when the saved access token still has more than 30 seconds of life. Apply this fallback at the refresh failure source only for the Git credential exchange; leave other callers unchanged. Add regression coverage for fallback, the expiry limit, and successful refresh.
Note
Medium Risk
Narrows auth failure handling for Git only, but still allows sending a near-expiry bearer when refresh fails; incorrect lifetime logic could accept tokens too close to expiry.
Overview
Git credential exchange can keep working when OAuth refresh fails but the on-disk access token still has meaningful time left.
Auth:
get_valid_token_with_sourcesaccepts an optionalrefresh_fallback_lifetime. After a failed refresh, if that lifetime is set andexpires_atis still more than that many seconds away, the existing access token is returned instead ofNot authenticated. Default callers passNone, so behavior is unchanged elsewhere.get_api_token_with_refresh_fallbackexposes this only for scoped use.Git: The
/api/git/credentialscall uses a 30s HTTP timeout and obtains the bearer via the refresh-fallback path (fallback window = same 30s), then applies it withapply_bearer_authrather than the standard API auth helper.Tests: Unit tests updated for the new parameter; integration test
near_expiry_token_refreshcovers refresh 503 with >30s left (reuse token), ≤30s left (quit), and successful refresh.Reviewed by Cursor Bugbot for commit 1e86c22. Bugbot is set up for automated code reviews on this repo. Configure here.