Skip to content

fix(credentials): token cache reuse issue for OAuthDeviceCode (DM-3772)#2605

Open
haakonvt wants to merge 1 commit into
masterfrom
fix-device-code-reuse-token-cache
Open

fix(credentials): token cache reuse issue for OAuthDeviceCode (DM-3772)#2605
haakonvt wants to merge 1 commit into
masterfrom
fix-device-code-reuse-token-cache

Conversation

@haakonvt
Copy link
Copy Markdown
Contributor

@haakonvt haakonvt commented May 5, 2026

Cherry-picked from v7: #2602

@haakonvt haakonvt requested review from a team as code owners May 5, 2026 09:44
@haakonvt haakonvt force-pushed the fix-device-code-reuse-token-cache branch from ffefb24 to 0dcac91 Compare May 5, 2026 09:46
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the token refresh logic for OAuthDeviceCode to prioritize cached access tokens and handle refresh tokens more robustly. It also updates the default Entra ID configuration with additional scopes and removes the audience parameter. Feedback focuses on correcting a "double leeway" calculation in token expiry, maintaining consistency by using CogniteOAuthError for OAuth errors, avoiding duplicated and hardcoded test skips in geospatial tests, and restoring removed assertions in unit tests to ensure comprehensive coverage.

I am having trouble creating individual review comments. Click here to see my feedback.

cognite/client/credentials.py (479-481)

high

This logic introduces a "double leeway" subtraction. The expiry is calculated by subtracting self.token_expiry_leeway_seconds, and then it's used as expires_in. The base class _OAuthCredentialProviderWithTokenRefresh then uses this value to calculate the expiration timestamp, and its __should_refresh_token method subtracts the leeway again during the check. This causes tokens to be refreshed much earlier than necessary. It's better to store the actual expiration duration and let the base class handle the leeway logic.

            expires_on = int(token.get("expires_on", 0))
            if expires_on > time.time() + self.token_expiry_leeway_seconds:
                credentials = {"access_token": token["secret"], "expires_in": expires_on - time.time()}
References
  1. Maintainability: Write code that is easy to modify and extend. Avoiding redundant logic like double leeway subtraction improves maintainability. (link)

cognite/client/credentials.py (524-526)

high

Use CogniteOAuthError instead of CogniteAuthError to maintain consistency with other OAuth-related error handling in this module (e.g., lines 187 and 904). CogniteOAuthError is specifically designed to encapsulate OAuth error responses with error and description fields, providing a structured and consistent error message across the SDK.

            raise CogniteOAuthError(
                response.get("error", "device_flow_error"), response.get("error_description", "Unknown error")
            )
References
  1. Consistency: Follow established patterns across the codebase. Using the specific OAuth error class maintains consistency with other credential providers. (link)

tests/tests_integration/test_api/test_geospatial.py (37-40)

high

The pytestmark for skipping geospatial tests is duplicated at line 70 in this module. Additionally, hardcoding a skip date in the far future (2026) effectively disables these integration tests for a long period. If the geospatial service is temporarily unavailable, consider using a more dynamic mechanism (like an environment variable check) to skip tests, rather than a long-term hardcoded date.

References
  1. Maintainability: Write code that is easy to modify and extend. Avoiding code duplication and using dynamic test skipping improves maintainability. (link)

tests/tests_unit/test_credential_providers.py (153-154)

high

The functional assertion verifying the authorization_header was removed in this test and several others (lines 160, 406, 412). This reduces the test's effectiveness as it no longer verifies that the loaded credential provider is correctly configured and capable of producing a valid authorization header. Please restore these assertions.

        assert isinstance(creds, OAuthDeviceCode)
        assert creds.authorization_header() == ("Authorization", "Bearer azure_token")
References
  1. Maintainability: Write code that is easy to modify and extend. Comprehensive tests are essential for maintainability. (link)

@haakonvt haakonvt force-pushed the fix-device-code-reuse-token-cache branch from 0dcac91 to e135d94 Compare May 5, 2026 09:54
@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.99%. Comparing base (03ba6fa) to head (e135d94).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2605   +/-   ##
=======================================
  Coverage   92.99%   92.99%           
=======================================
  Files         482      482           
  Lines       48995    48996    +1     
=======================================
+ Hits        45564    45566    +2     
+ Misses       3431     3430    -1     
Files with missing lines Coverage Δ
cognite/client/credentials.py 85.49% <100.00%> (+1.24%) ⬆️
tests/tests_unit/test_credential_providers.py 100.00% <100.00%> (ø)

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@haakonvt haakonvt changed the title fix(credentials): token cache reuse issue for OAuthDeviceCode fix(credentials): token cache reuse issue for OAuthDeviceCode (DM-3772) May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant