Skip to content

Refresh pooled connections before credential expiry - #4216

Draft
lh0156 wants to merge 1 commit into
redis:masterfrom
lh0156:agent/connection-lifetime
Draft

Refresh pooled connections before credential expiry#4216
lh0156 wants to merge 1 commit into
redis:masterfrom
lh0156:agent/connection-lifetime

Conversation

@lh0156

@lh0156 lh0156 commented Jul 26, 2026

Copy link
Copy Markdown

Fixes #3895

Motivation

Connection pools can keep a socket alive beyond the lifetime of the credentials used to authenticate it. This is especially problematic for rotating credentials such as Azure Workload Identity tokens: the pool continues to hand out an established connection, which eventually fails authentication after the token expires.

Solution

  • Add an opt-in max_connection_lifetime connection setting; None preserves current behavior.
  • Record the lifetime after a connection's handshake completes.
  • On the next checkout after the lifetime is reached, close the idle socket and reconnect it before returning it to the caller.
  • Refresh credentials through the existing credential provider during reconnect.
  • Apply the same lifecycle behavior to sync, asyncio, and Sentinel-managed connections.
  • Accept the setting in Redis URLs and document the checkout semantics.
  • Never interrupt an in-use command; refresh occurs when the connection is checked out again.

Tests

  • TDD regression coverage for expired and non-expired sync and async connections.
  • Validation for positive lifetime values and URL parsing in both implementations.
  • Full sync connection suite: 95 passed, 2 skipped.
  • Full async connection suite: 66 passed, 2 skipped.
  • invoke linters, compileall, and git diff --check passed.

The local pool/Sentinel integration suites require services not available in this checkout: the local Redis server has DEBUG disabled and no Sentinel is listening on the configured ports.

@petyaslavova

Copy link
Copy Markdown
Collaborator

Thanks for picking this up, and for posting the design note on #3895 before starting — that's appreciated.

Before going further on the implementation, I'd like to settle the underlying need.
redis-py already refreshes rotating credentials on live pooled connections: with a StreamingCredentialProvider (e.g. redis-entraid's EntraIdCredentialsProvider), TokenManager renews ahead of expiry and ConnectionPool.re_auth_callback re-AUTHs idle connections immediately, while in-use ones re-authenticate right after their current command. That covers standalone pools, pipelines, cluster nodes and RESP3 pub/sub, and is exercised by the Entra ID tests in tests/test_credentials.py.
Could you share a reproduction where a StreamingCredentialProvider is configured and a pooled connection still fails authentication? That's the evidence we'd need to justify a new connection setting.

Two things about the current shape are worth flagging regardless. max_connection_lifetime isn't in REDIS_ALLOWED_KEYS, so RedisCluster silently drops it (and async RedisCluster.from_url raises TypeError), and it isn't accepted by Redis.__init__ at all — only via from_url. Because expiry is only checked in connect_check_health, the setting also never applies to single_connection_client=True clients or pub/sub connections, which are the sockets most likely to outlive a token.

Separately, we're leaning towards solving this at the pool layer instead: an age/idle sweep over pooled connections that reuses the existing mark_for_reconnect() / should_reconnect() mechanism, so idle and in-use connections are retired consistently across standalone, cluster and sentinel, and the pool can also shrink back after a burst. If you'd like to re-target the PR onto that design I'd be glad to review it. I'll leave this as a draft in the meantime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Restrict total connection lifetime to prevent using invalidated credentials

2 participants