GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — fix(auth): enforce exp/iat claims and propagate leeway in verify_token JWKS branch by phamtoanbaoquan23121985 · Pull Request #19050 · googleapis/google-cloud-python ConversationPull Request: fix(auth): enforce exp/iat claims and propagate leeway in verify_token JWKS branchTarget Branch: DescriptionIn Prior to this PR, two discrepancies existed between the JWKS branch and the certificate-mapping (PEM) branch:
This pull request resolves both discrepancies by:
Specifications & References
Testing & VerificationAll 90 unit, async, and differential tests pass with exit code
Differential Cryptographic Matrix (11 Scenarios)
Checklist
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
…n JWKS branch
In `google.oauth2.id_token.verify_token`, when certificates are delivered
in JSON Web Key Set (JWKS) format (containing `"keys"`), verification is
delegated to `pyjwt`'s `jwt_lib.decode()`.
Prior to this fix:
1. `options={"require": ["exp", "iat"]}` was omitted, causing tokens lacking
an expiration claim (`exp`) or issued-at claim (`iat`) to be accepted as
valid without lifetime boundaries. In contrast, the certificate-mapping (PEM)
branch strictly enforces `exp` and `iat` presence via `_verify_iat_and_exp`.
2. `leeway=clock_skew_in_seconds` was omitted, causing user-configured clock
skew tolerance to be silently discarded in the JWKS branch, rejecting tokens
that had acceptable time drift within the configured skew window.
This change aligns JWKS verification semantics with the certificate-mapping
branch and OpenID Connect Core 1.0 (Section 3.1.3.7) by:
- Requiring both `exp` and `iat` claims in the PyJWT options dictionary.
- Propagating `leeway=clock_skew_in_seconds` to `jwt_lib.decode()`.
- Adding unit test verification for leeway propagation and require claims.
- Adding comprehensive differential tests verifying JWKS and PEM parity.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code ReviewThis pull request updates the JWK token verification path in
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Comment on lines
+195
to
+225
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using small time offsets (e.g., 5 seconds) with real system time (time.time()) can lead to test flakiness in slow CI environments. If the test runner takes more than 5 seconds to execute between generating the token and verifying it, the token will be considered fully expired even with the 10-second leeway, causing the test to fail. Increasing the time offsets and leeway (e.g., to 5 and 10 minutes) provides a robust buffer. def test_differential_clock_skew_expired_within_leeway(crypto_env): now = int(time.time()) payload = { "iss": "https://accounts.google.com", "sub": "user-123", "aud": "my-client-app", "iat": now - 1000, "exp": now - 300, # expired 5 minutes ago } token = _make_token(crypto_env, payload) # With 10 minutes leeway, both must accept crypto_env["server"].mode = "jwks" info_jwks = id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=600, ) assert info_jwks["sub"] == "user-123" crypto_env["server"].mode = "pem" info_pem = id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=600, ) assert info_pem["sub"] == "user-123"
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Comment on lines
+228
to
+259
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To maintain consistency with the other clock skew tests and ensure robustness against slow CI environments, increase the expiration offset and leeway values (e.g., to 10 minutes expired and 5 minutes leeway). def test_differential_clock_skew_expired_outside_leeway(crypto_env): now = int(time.time()) payload = { "iss": "https://accounts.google.com", "sub": "user-123", "aud": "my-client-app", "iat": now - 1000, "exp": now - 600, # expired 10 minutes ago } token = _make_token(crypto_env, payload) # With 5 minutes leeway, both must reject crypto_env["server"].mode = "jwks" with pytest.raises(pyjwt.ExpiredSignatureError): id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=300, ) crypto_env["server"].mode = "pem" with pytest.raises(exceptions.InvalidValue): id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=300, )
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Comment on lines
+261
to
+291
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using small time offsets (e.g., 5 seconds) with real system time (time.time()) can lead to loss of test coverage in slow CI environments. If the test runner takes more than 5 seconds to execute, the iat claim will no longer be in the future, meaning the test will no longer actually verify the future iat leeway handling. Increasing the time offsets and leeway (e.g., to 5 and 10 minutes) ensures the test remains valid. def test_differential_clock_skew_future_iat_within_leeway(crypto_env): now = int(time.time()) payload = { "iss": "https://accounts.google.com", "sub": "user-123", "aud": "my-client-app", "iat": now + 300, # issued 5 minutes in future "exp": now + 3600, } token = _make_token(crypto_env, payload) # With 10 minutes leeway, both must accept crypto_env["server"].mode = "jwks" info_jwks = id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=600, ) assert info_jwks["sub"] == "user-123" crypto_env["server"].mode = "pem" info_pem = id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=600, ) assert info_pem["sub"] == "user-123"
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Comment on lines
+294
to
+325
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using small time offsets (e.g., 20 seconds) with real system time (time.time()) can lead to test flakiness in slow CI environments. If the test runner takes more than 10 seconds to execute, the remaining future time will fall within the 10-second leeway, causing the token to be accepted and the test to fail. Increasing the time offsets and leeway (e.g., to 10 and 5 minutes) ensures the test remains robust. def test_differential_clock_skew_future_iat_outside_leeway(crypto_env): now = int(time.time()) payload = { "iss": "https://accounts.google.com", "sub": "user-123", "aud": "my-client-app", "iat": now + 600, # issued 10 minutes in future "exp": now + 3600, } token = _make_token(crypto_env, payload) # With 5 minutes leeway, both must reject crypto_env["server"].mode = "jwks" with pytest.raises(pyjwt.ImmatureSignatureError): id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=300, ) crypto_env["server"].mode = "pem" with pytest.raises(exceptions.InvalidValue): id_token.verify_token( token, crypto_env["req"], audience="my-client-app", certs_url=crypto_env["server"].url, clock_skew_in_seconds=300, )
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsThis branch has not been deployedNo deployments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Reviewers1 more reviewerAt least 1 approving review is required to merge this pull request. Uh oh!
There was an error while loading. Please reload this page. AssigneesNo one assignedLabels
None yet
ProjectsMilestoneNo milestoneDevelopmentSuccessfully merging this pull request may close these issues. Uh oh!
There was an error while loading. Please reload this page. Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |