Repository navigation
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.
Beyond the inline findings, I also checked three things and ruled them out:
- No other client-side expiry comparison still uses the inclusive boundary: the two changed lines are the only ones under
src/mcp/client/auth. - The new identity-assertion test does hit the equality case:
calculate_token_expiryonly special-casesNone, soexpires_in=0under the patched clock yields an expiry equal to "now". mockis already imported intests/client/test_auth.py.
Extended reasoning...
The change flips two access-token expiry comparisons from <= to < in the OAuth client (src/mcp/client/auth/oauth2.py and src/mcp/client/auth/extensions/identity_assertion.py) and adds two tests, which is client auth code, so it is not approved automatically. The note records only the checks that came up clean; the inline comments cover the rest.
| pass | ||
|
|
||
|
|
||
| def test_a_token_is_invalid_at_its_expiry_instant(oauth_provider: OAuthClientProvider): |
There was a problem hiding this comment.
🟡 nit (optional): The new top-level test test_a_token_is_invalid_at_its_expiry_instant has no return type hint, which AGENTS.md asks for on all code. Its sibling added in the same change, at tests/client/auth/extensions/test_identity_assertion.py:329, is annotated -> None. Fix: add -> None to the signature at tests/client/test_auth.py:3672.
Why this was flagged
No runtime trigger applies; this is a convention check on the test code added since the last review. The signature at tests/client/test_auth.py:3672 reads def test_a_token_is_invalid_at_its_expiry_instant(oauth_provider: OAuthClientProvider): with a typed parameter but no return annotation. AGENTS.md line 50 says "Type hints required for all code". The other test this change adds, test_stored_token_is_not_sent_at_its_expiry_instant at tests/client/auth/extensions/test_identity_assertion.py:329, does carry -> None, so the two new tests are inconsistent with each other. The base branch has no such function; older tests in the same file (for example tests/client/test_auth.py:1170) also omit the annotation, which is legacy precedent rather than the rule. Nothing enforces it: pyright infers the return type and the test passes unchanged.
Verification: AGENTS.md line 50 reads "- Type hints required for all code". The diff adds tests/client/test_auth.py:3672 def test_a_token_is_invalid_at_its_expiry_instant(oauth_provider: OAuthClientProvider): with an annotated parameter but no return annotation, so the function is only partially type-hinted. Nothing breaks.
Finding ID: f-570feb36
Fixes #3729
The OAuth client now treats an access token as expired at its expiry time, not only after it.
Motivation and Context
OAuthContext.is_token_valid()and the cached-token check inIdentityAssertionOAuthProvidercomparedtime.time() <= expiry, so a token was still sent at the exact instant it expired. Withexpires_in=0, the expiry equals the issuance time, so the client could reuse a token that should never be used, which showed up as intermittent failures on platforms with a coarse clock. RFC 7519 §4.1.4 definesexpas the time "on or after which" the token must not be accepted, so both checks now use<.How Has This Been Tested?
test_auth.py: the token is invalid when the clock equalstoken_expiry_time.test_identity_assertion.py: a stored token withexpires_in=0is not attached when the clock has not moved.strict-no-coverand pyright clean.Breaking Changes
None: a token is refreshed or reacquired one clock tick earlier, at its expiry instant.
Types of changes
Checklist
help wanted, or I'm a maintainer)Additional context
The source change is the same as the one proposed by @pei711 in #3730, which was closed by the linked-issue bot; this adds a test for the identity-assertion path as well.
AI Disclaimer
This PR was developed with the assistance of either Claude or Codex. I've reviewed and verified the changes.