Skip to content

feat(credentials): let users choose the account for interactive login (DM-3512) - #2730

Open
yangru96 wants to merge 1 commit into
masterfrom
fix/interactive-login-multiple-accounts-dm-3512
Open

feat(credentials): let users choose the account for interactive login (DM-3512)#2730
yangru96 wants to merge 1 commit into
masterfrom
fix/interactive-login-multiple-accounts-dm-3512

Conversation

@yangru96

Copy link
Copy Markdown

Description

OAuthInteractive silently used the first account it found in the token cache, so users signed in with several accounts had no way to choose and often ended up on the wrong one.

Add prompt and login_hint to OAuthInteractive, its default_for_entra_id helper, (Async)CogniteClient.default_oauth_interactive and the YAML/JSON config accepted by load(). Pass prompt="select_account" to pick the account in the browser, or login_hint to name it up front and skip being asked. Once signed in, later token refreshes stay on that account without prompting again.

Behavior change: when the token cache holds several accounts and neither argument is given, the browser now opens with an account picker instead of silently using an arbitrary account. A single cached account is still reused silently, so users with one account are unaffected.

Checklist:

  • [x Tests added/updated.
  • Documentation updated. Documentation is generated from docstrings - these must be updated according to your change. If a new method has been added it should be referenced in cognite.rst in order to generate docs based on its docstring.
  • The PR title follows the Conventional Commit spec.

@yangru96
yangru96 requested review from a team as code owners July 30, 2026 14:50

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

Copy link
Copy Markdown
Contributor

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 adds support for prompt and login_hint parameters to the interactive OAuth flow in OAuthInteractive and default_oauth_interactive across sync and async clients, enabling explicit account selection and login hints. Feedback was provided to use credentials.get("id_token_claims") or {} to defensively handle cases where the claims key exists but is None.

Comment thread cognite/client/credentials.py Outdated

@haakonvt haakonvt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A few late night comments from me, overall looks solid. I will attempt to test it out in the morning and connect you with the guy that reported this initially, cc @spex66

Comment thread cognite/client/credentials.py
Comment thread cognite/client/credentials.py Outdated
Comment thread cognite/client/credentials.py
Comment thread cognite/client/credentials.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am a bit sceptical to the real value of several of these tests (and existing tbh).

To what extent have you tested this new logic yourself? Especially with the caching it is super easy to screw something up (speaking from experience here 😅 )

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fair. The reason I'd keep them is that the logic branches on three things at once: how many accounts are cached (none / one / several), whether prompt was passed, and whether we already signed in this session. The "several accounts" branch also needs a second real account, so it's hard to hit by hand.

I just tested it for real though: a temp script running locally against the "quick start sdk" app registration in Azure (Graph as the scope), with a real on-disk cache and a fresh provider each step.

  1. Fresh cache, no args — browser opens, no picker.
  2. Run again, no args — no browser, cached account reused.
  3. login_hint for that same account — no browser, reused silently.
  4. login_hint for an account I've never used — browser opens with login_hint=... in the authorize URL; whether Entra pre-fills it or shows the picker depends on what sessions the browser already has.
  5. prompt="select_account" — picker appears even though I'd signed in.

All as expected.

@haakonvt haakonvt changed the title feat: let users choose the account for interactive login (DM-3512) feat(credentials): let users choose the account for interactive login (DM-3512) Jul 30, 2026
OAuthInteractive silently used the first account it found in the token
cache, so users signed in with several accounts had no way to choose and
often ended up on the wrong one.

Add prompt and login_hint to OAuthInteractive, its
default_for_entra_id helper, (Async)CogniteClient.default_oauth_interactive
and the YAML/JSON config accepted by load(). Pass
prompt="select_account" to pick the account in the browser, or
login_hint to name it up front and skip being asked. Once signed in,
later token refreshes stay on that account without prompting again.

Behavior change: when the token cache holds several accounts and neither
argument is given, the browser now opens with an account picker instead of
silently using an arbitrary account. A single cached account is still
reused silently, so users with one account are unaffected.
@yangru96
yangru96 force-pushed the fix/interactive-login-multiple-accounts-dm-3512 branch from 584a645 to b0e826a Compare July 31, 2026 10:47
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.57143% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.73%. Comparing base (0744eb7) to head (b0e826a).
⚠️ Report is 9 commits behind head on master.

Files with missing lines Patch % Lines
cognite/client/_cognite_client.py 50.00% 1 Missing ⚠️
cognite/client/_sync_cognite_client.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2730      +/-   ##
==========================================
+ Coverage   93.70%   93.73%   +0.02%     
==========================================
  Files         504      505       +1     
  Lines       51112    51437     +325     
==========================================
+ Hits        47897    48212     +315     
- Misses       3215     3225      +10     
Files with missing lines Coverage Δ
cognite/client/credentials.py 87.31% <100.00%> (+1.82%) ⬆️
tests/tests_unit/test_credential_providers.py 100.00% <100.00%> (ø)
cognite/client/_cognite_client.py 95.81% <50.00%> (ø)
cognite/client/_sync_cognite_client.py 88.88% <50.00%> (ø)

... and 24 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.

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.

2 participants