Skip to content

Connection pool should separate identities for access-token and integrated auth connections #651

Description

@jahnvi480

Summary

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:

  1. 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.

  2. For built-in Authentication=ActiveDirectory*: Derive a discriminator from the credential type + principal (e.g., hash of auth type + UID if present).

  3. 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.

Related

Metadata

Metadata

Assignees

Labels

area: connectivity-authConnection lifecycle, Entra/SP/NTLM auth, tokens, TLS, conn-string parsing, Fabric endpoints.enhancementNew feature or request
No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions