You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Connection pool should separate identities for access-token and integrated auth connections #651
The current connection pool in mssql-python keys only on the sanitized connection string. It does not account for the identity/security context of the user. This means different principals connecting to the same Server/Database can collide in the same pool bucket — a silent privilege escalation risk.
As a stopgap, PR #603 (token_provider=) disables pooling for all access-token connections. This issue tracks the proper fix: extending the pool key to include identity information so pooling can remain enabled safely.
Problem
The native pool (ddbc_bindings) receives (connection_string, pooling_bool, attrs_before) but only the connection string is used as the pool key. The access token lives in attrs_before[SQL_COPT_SS_ACCESS_TOKEN] and is invisible to the pool. Two users authenticating with different tokens to the same server/database get the same pool bucket.
Auth paths affected
Auth path
Identity visible to pool?
Risk
token_provider= (custom credential)
❌ No
Different principals share pool bucket
Authentication=ActiveDirectoryDefault
❌ No
Same — token injected via attrs_before
Authentication=ActiveDirectoryInteractive
❌ No
Same
Authentication=ActiveDirectoryDeviceCode
❌ No
Same
Authentication=ActiveDirectoryServicePrincipal
❌ No
Same (bulk copy path uses raw token)
Windows Integrated Auth (NTLM/Kerberos)
❌ No
SSPI token negotiated by driver, not exposed to pool key
SQL Auth (UID/PWD)
✅ Yes
Credentials are in the connection string (pool key)
Proposed solution
Extend the native pool key to include an identity discriminator alongside the connection string. Options to explore:
For token_provider=: Use id(token_provider) (object identity) as a pool key component. Same credential instance → same pool bucket. New instance → new bucket. This aligns with the principle that a new security context = a new provider instance.
For built-in Authentication=ActiveDirectory*: Derive a discriminator from the credential type + principal (e.g., hash of auth type + UID if present).
For Windows Integrated Auth (NTLM/Kerberos): The SSPI token is negotiated internally by the driver and not exposed to the Python layer. Needs investigation into whether the native layer can extract the principal identity for the pool key.
Cross-driver reference
Driver
Pool identity separation?
How
JDBC (mssql-jdbc)
✅ Yes
Includes access token in pool key
PHP
✅ Yes
Separates pools based on access token
pyodbc
❌ No
Recommends disabling pooling for token auth
Current workaround
PR #603 disables pooling (self._pooling = False) whenever SQL_COPT_SS_ACCESS_TOKEN is present in attrs_before. This covers token_provider=, built-in Authentication=ActiveDirectory*, and raw attrs_before token paths. Safe but loses pooling benefits.
Additional deliverable
Document which auth paths have identity-aware pooling vs. which don't — either in the docs or a wiki page — so users understand the current limitations.
Filed #659 for a related but distinct performance aspect: with Authentication=ActiveDirectory*, Connection.__init__ acquires an access token on every connect() before the pool is consulted, so on a pool hit the token is materialized but never used. A proper identity-aware pool key (this issue) is the prerequisite for letting a same-identity pool hit skip token acquisition entirely.
Activity
github-actions commentedon Jun 30, 2026
Hi Jahnvi Thakkar (@jahnvi480), thank you for opening this issue!
Our team will review it shortly. We aim to triage all new issues within 24-48 hours and get back to you.
If you have additional information to share, please feel free to update the issue.
Thank you for your patience!
sdebruyn commentedon Jul 2, 2026
Filed #659 for a related but distinct performance aspect: with
Authentication=ActiveDirectory*,Connection.__init__acquires an access token on everyconnect()before the pool is consulted, so on a pool hit the token is materialized but never used. A proper identity-aware pool key (this issue) is the prerequisite for letting a same-identity pool hit skip token acquisition entirely.Identity-aware connection pooling: isolate pools by identity (#651)
FEAT: token-expiry capture and identity-aware pool key (#660)
RELEASE:1.13.0 (#707)