Skip to content

feat(networking): surface AuthenticationExpired for unrecoverable OAuth logins#2536

Draft
nichmor wants to merge 1 commit into
conda:mainfrom
nichmor:oauth-expired-reauth
Draft

feat(networking): surface AuthenticationExpired for unrecoverable OAuth logins#2536
nichmor wants to merge 1 commit into
conda:mainfrom
nichmor:oauth-expired-reauth

Conversation

@nichmor

@nichmor nichmor commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Description

Builds on the OAuth refresh handling already in main (OAuthRefreshOutcome /
OAuthRefreshFailure, which drops an expired access token when it cannot be
refreshed and sends the request unauthenticated so the auth-challenge
middleware can take over).

This adds a typed AuthenticationExpired { host } error for the case where
the stored login itself is no longer usable. In AuthenticationMiddleware:

  • after a refresh attempt, inspect refresh_result.failure() and treat only
    MissingRefreshToken and ReauthenticationRequired as "the login is dead"
    (transient refresh problems keep the existing log-and-continue behavior);
  • only when the dead credential was actually dropped (so the request goes out
    unauthenticated) remember the host;
  • if that request still comes back 401/403, return
    AuthenticationExpired { host } so callers can prompt the user to
    re-authenticate (e.g. re-run their login command).

AuthenticationExpired is re-exported from the crate root.

How Has This Been Tested?

  • pixi run cargo-fmt and pixi run -- cargo clippy -p rattler_networking --all-targets are clean.
  • Relies on the existing oauth_refresh / authentication_middleware unit
    tests in main for the refresh-outcome paths.
pixi run -- cargo nextest run -p rattler_networking

Opened as a draft: no test yet asserts the new AuthenticationExpired
path end to end — happy to add one before marking ready.

AI Disclosure

  • This PR contains AI-generated content.
    • I have tested any AI-generated content in my PR.
    • I take responsibility for any AI-generated content in my PR.

Tools: Claude (Claude Code, Opus 4.8)

what we have done in this branch?
can you create a draft pr?
ok, just make this branch to be exactly the same as main for now
can you push it again? I've made some changes there

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added sufficient tests to cover my changes.

…th logins

When a stored OAuth credential is expired, cannot be refreshed because the
login itself is no longer usable (no refresh token, or the server says
re-authentication is required), and the resulting unauthenticated request
still comes back 401/403, return a typed AuthenticationExpired { host }
error so callers can prompt the user to log in again.

Builds on main's OAuthRefreshOutcome: reads refresh_result.failure() and
only treats MissingRefreshToken / ReauthenticationRequired as needing
re-auth, leaving transient refresh problems to log-and-continue.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant