Skip to content

snow-3784431: Part 2 - token cache key v2 fixup - #2973

Closed
sfc-gh-mhofman wants to merge 8 commits into
mainfrom
sfc-gh-mhofman/SNOW-3784431-token-cache-key-v2-fixup
Closed

sfc-gh-mhofman wants to merge 8 commits into
mainfrom
sfc-gh-mhofman/SNOW-3784431-token-cache-key-v2-fixup

Conversation

@sfc-gh-mhofman

@sfc-gh-mhofman sfc-gh-mhofman commented Jul 22, 2026 •

Copy link
Copy Markdown
Collaborator

This is a follow-up change to #3030 and should be merged/released altogether.

This PR

  • Moves token_type out of the hashed keyData into the key prefix:
    SnowflakeTokenCache.v2.<TokenType>.<sha256hex>
  • Flow-specific keyData:
    • OAuth (OauthAccessToken, OauthRefreshToken, DpopBundledAccessToken): 4 fields — idp, role, snowflake, username
    • MFA / ID token (MfaToken, IdToken): 2 fields — snowflake, username only (idp/role absent — not part of those auth calls)
  • TokenType enum values → PascalCase (MfaToken, OauthAccessToken, …) matching the cross-driver contract
  • normalize_url / normalize_identifier → lowercase instead of uppercase
  • TokenKey.idp and role → optional (default ""); MFA/ID call sites in _auth.py omit them
  • _LEGACY_TOKEN_TYPE_VALUES added so backward migration still emits the old SCREAMING_SNAKE_CASE type strings

After both PRs

  • Key format: SnowflakeTokenCache.v2.<TokenType>.<sha256hex(compact-sorted-json)>
  • Collisions impossible across accounts (different idp), roles, token types, and flows
  • MFA/ID and OAuth produce structurally different keys (different prefix + different field set)
  • Existing cache entries from both prior layouts transparently migrated on first access

Test plan

  • test/unit/test_token_cache_key.py — 32 tests (normalization, two cross-driver golden hash vectors, structural MFA assertions, dimension isolation)
  • test/unit/test_auth_mfa.py — MFA token cache round-trip
  • test/unit/test_linux_local_file_cache.py — file cache tests (Linux only)

sfc-gh-mhofman and others added 4 commits July 15, 2026 14:23
Extends TokenKey to five named fields (token_type, idp, snowflake,
username, role) and introduces normalize_url/normalize_identifier helpers
plus build_cache_key, which produces a stable SnowflakeTokenCache.v2.<sha256>
key used by both KeyringTokenCache and FileTokenCache.  Threads the new
fields through all auth call sites (_auth.py, _oauth_base.py, oauth_code.py,
connection.py) and updates every affected test file, including a new
test/unit/test_token_cache_key.py that validates the cross-driver golden
hash vector.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ments

Co-authored-by: Cursor <cursoragent@cursor.com>
Threads the role field through the async auth path (aio/_connection.py and
aio/auth/_auth.py) so async SSO/OAuth/MFA flows build the same v2 cache keys
as their sync counterparts, and replaces the stale positional TokenKey call
sites in the async authenticate override.

Extends legacy migration so both KeyringTokenCache and FileTokenCache read
and migrate entries from the two prior key layouts (hashed-account and
string-key), deriving the legacy host from the IdP hostname for OAuth tokens
and the Snowflake host otherwise via shared _legacy_string_key/_legacy_hash_key
helpers. Corrects the KeyringTokenCache docstring and updates the manual async
SSO test to the five-field TokenKey. Adds migration coverage for both backends.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov-commenter

Copy link
Copy Markdown

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

…rge conflict

The old TokenKey call sites for ID/MFA passed args positionally as
TokenKey(host, user, type) into a (user, host, tokenType) dataclass,
swapping the fields. The resulting string_key() produced USER:HOST:TYPE,
not HOST:USER:TYPE. _legacy_string_key now replicates this swap for
ID_TOKEN and MFA_TOKEN so existing pre-v2 cache entries are found and
migrated correctly. OAuth tokens were called in the correct order and
are unaffected.

Also resolves the DESCRIPTION.md merge conflict from the main merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sfc-gh-mhofman sfc-gh-mhofman reopened this Sep 8, 2026
@sfc-gh-mhofman sfc-gh-mhofman changed the title snow-3784431 token cache key v2 fixup snow-3784431: Part 2 - token cache key v2 fixup Sep 8, 2026
sfc-gh-mhofman and others added 3 commits September 8, 2026 13:47
Resolve conflicts in DESCRIPTION.md (keep both NEXT_RELEASE entries) and
aio/auth/_auth.py (add SQLSTATE_AUTHORIZATION_FAILURE import from main,
keep TokenKey import from branch). Fix new test_oauth_infinite_loop_fix.py
tests introduced by main that still used the old .tokenType attribute name
(renamed to .token_type in this branch).

Co-authored-by: Cursor <cursoragent@cursor.com>
…c keyData

- Move token_type out of keyData into the key prefix:
    SnowflakeTokenCache.v2.<TOKEN_TYPE>.<sha256hex(canonical_json)>
- Use flow-specific keyData:
  * OAuth (OAUTH_ACCESS_TOKEN, OAUTH_REFRESH_TOKEN, DPOP_BUNDLED_ACCESS_TOKEN):
    4 fields — idp, role, snowflake, username
  * MFA / ID token (MFA_TOKEN, ID_TOKEN):
    2 fields — snowflake, username only
- Make TokenKey.idp and TokenKey.role optional (default ""); required args
  are now token_type, snowflake, username — matching the MFA/ID flow.
- Update all MFA and ID_TOKEN call sites in _auth.py to omit idp and role.
- Replace old 5-field golden hash test with vectors A (OAuth/DPoP) and B (MFA).
- Add test_mfa_key_has_no_idp_or_role and test_mfa_vs_oauth_key_differ_...
- Update DESCRIPTION.md changelog entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
…n type

- normalize_url now lowercases instead of uppercases; normalize_identifier
  returns verbatim for any value containing a double-quote, lowercases otherwise.
- TokenType enum values changed to PascalCase (MfaToken, OauthAccessToken, …)
  matching the cross-driver v2 key contract update.
- _OAUTH_TYPES frozenset updated to PascalCase values.
- _legacy_string_key retains SCREAMING_SNAKE_CASE via _LEGACY_TOKEN_TYPE_VALUES
  to preserve backward-compatible migration of pre-v2 cache entries.
- All affected unit tests updated; both golden hash vectors (A and B) pass.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sfc-gh-mhofman
sfc-gh-mhofman force-pushed the sfc-gh-mhofman/SNOW-3784431-token-cache-key-v2-fixup branch from 999971c to c316492 Compare September 8, 2026 12:02
@sfc-gh-mhofman
sfc-gh-mhofman marked this pull request as ready for review September 8, 2026 12:10
@sfc-gh-mhofman
sfc-gh-mhofman requested a review from a team as a code owner September 8, 2026 12:10
@sfc-gh-mhofman

Copy link
Copy Markdown
Collaborator Author

Moved to internal repo.

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