Skip to content

Fix websocket connection leak during authentication#92

Merged
sk-keeper merged 3 commits intoKeeper-Security:releasefrom
m-k8s:fix/asyncio-cleanup
Nov 13, 2025
Merged

Fix websocket connection leak during authentication#92
sk-keeper merged 3 commits intoKeeper-Security:releasefrom
m-k8s:fix/asyncio-cleanup

Conversation

@m-k8s
Copy link
Contributor

@m-k8s m-k8s commented Nov 13, 2025

Fix websocket connection leak during authentication

Problem

When applications using keeper-sdk exit after authentication with 2FA, device approval, or SSO data key requests, the asyncio event loop is closed while background tasks (push notification websockets) are still running, causing error messages:

ERROR:asyncio:Task was destroyed but it is pending!
task: <Task pending name='Task-1' coro=<BasePushNotifications.main_loop()...>>
RuntimeError: Event loop is closed

Root Cause

During authentication requiring interactive approval, a push notification websocket (LoginPushNotifications) is created to handle:

  • 2FA authentication
  • Device approval requests
  • SSO data key sharing

The bug: This websocket was never closed after successful login.

When the application exits, the websocket connection is still active, causing asyncio to report pending tasks that are destroyed during shutdown.

Solution

Close login.push_notifications in _on_logged_in() after authentication completes.

Previously, when applications using SSO authentication exited, the
asyncio event loop was closed while background tasks were still
running, resulting in:
- ERROR: Task was destroyed but it is pending
- RuntimeError: Event loop is closed

This issue occurred specifically with SSO authentication flows that
use push notifications, but not with password-only authentication.

This fix ensures proper cleanup by:
1. Cancelling all pending tasks before stopping the event loop
2. Giving tasks time (0.3s) to handle CancelledError gracefully
3. Waiting for the event loop thread to finish before closing

This prevents "Task was destroyed but it is pending" errors when
shutting down applications that use SSO with push notifications.
During SSO authentication flows, a push notification websocket
(LoginPushNotifications) is created to handle 2FA, device approval,
and SSO data key requests.

This websocket was never closed after successful login, causing
it to remain active until application shutdown. This resulted in
asyncio errors about pending tasks being destroyed.

Fix: Close login.push_notifications in _on_logged_in() immediately
after authentication completes and before any post-login setup.
@sk-keeper sk-keeper changed the base branch from master to release November 13, 2025 20:40
@sk-keeper sk-keeper merged commit 43c5a10 into Keeper-Security:release Nov 13, 2025
2 checks passed
@m-k8s m-k8s changed the title Fix asyncio event loop cleanup with SSO auth Fix websocket connection leak during authentication Nov 13, 2025
sk-keeper pushed a commit that referenced this pull request Feb 27, 2026
* Fix asyncio event loop cleanup with SSO auth

Previously, when applications using SSO authentication exited, the
asyncio event loop was closed while background tasks were still
running, resulting in:
- ERROR: Task was destroyed but it is pending
- RuntimeError: Event loop is closed

This issue occurred specifically with SSO authentication flows that
use push notifications, but not with password-only authentication.

This fix ensures proper cleanup by:
1. Cancelling all pending tasks before stopping the event loop
2. Giving tasks time (0.3s) to handle CancelledError gracefully
3. Waiting for the event loop thread to finish before closing

This prevents "Task was destroyed but it is pending" errors when
shutting down applications that use SSO with push notifications.

* Revert "Fix asyncio event loop cleanup with SSO auth"

This reverts commit 8364e1c.

* Close login websocket after authentication

During SSO authentication flows, a push notification websocket
(LoginPushNotifications) is created to handle 2FA, device approval,
and SSO data key requests.

This websocket was never closed after successful login, causing
it to remain active until application shutdown. This resulted in
asyncio errors about pending tasks being destroyed.

Fix: Close login.push_notifications in _on_logged_in() immediately
after authentication completes and before any post-login setup.
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