mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2026-05-07 03:49:54 -05:00
[GH-ISSUE #6788] AuthRequestResponse notification incorrectly sent to approving device, causing duplicate notification on Android #11349
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @ivulit on GitHub (Feb 4, 2026).
Original GitHub issue: https://github.com/dani-garcia/vaultwarden/issues/6788
Prerequisites
Vaultwarden Support String
Your environment (Generated via diagnostics page)
Config & Details (Generated via diagnostics page)
Show Config & Details
Config:
Vaultwarden Build Version
1.35.2
Deployment method
Official Container Image
Custom deployment method
No response
Reverse Proxy
nginx 1.28.0
Host/Server Operating System
Linux
Operating System Version
Alpine Linux v3.23
Clients
Android
Client Version
Android 2026.1.0 (21141)
Steps To Reproduce
Expected Result
Device B shows no further notifications after approval. Device A receives the approval and completes login
Actual Result
Device B receives an AuthRequestResponse (type 16) push notification immediately after approving, which appears as a duplicate auth request notification on Android.
Logs
Screenshots or Videos
No response
Additional Context
Analysis
In put_auth_request (src/api/core/accounts.rs:1591-1592), two notification calls are made after approval:
ant.send_auth_response(&auth_request.user_uuid, &auth_request.uuid).await;
nt.send_auth_response(&auth_request.user_uuid, &auth_request.uuid, &headers.device, &conn).await;
ant.send_auth_response() sends through the anonymous WebSocket hub, keyed by auth_request_id — this correctly reaches only Device A (the requesting device).
nt.send_auth_response() does two things:
Both reach Device B (the approving device), which should not receive AuthRequestResponse at all.
Official Bitwarden server behavior
In the official server, PushAuthRequestResponseAsync (IPushNotificationService.cs:387-399) creates a single PushNotification with ExcludeCurrentContext = true.
This notification is routed through all push engines:
authenticated _hubContext. This is the key difference from AuthRequest (type 15), which is sent through _hubContext.Clients.User() (line 130).
(BuildTag, line 94) builds an exclusion tag !deviceIdentifier:{identifier}, preventing the push from reaching the approving device.
As a result, Device B receives nothing on the official server.
This analysis was conducted with the help of Claude (Anthropic).
@rafaelfariasbsb commented on GitHub (Feb 26, 2026):
Root Cause Analysis
I traced the notification flow after a device approves an auth request in
put_auth_request(src/api/core/accounts.rs:1584-1585):Call 1 —
ant.send_auth_response()(anonymous WebSocket hub):Sends to the anonymous hub keyed by
auth_request_id(notifications.rs:556). Only Device A (the requesting device) is subscribed to this token, so this is correct.Call 2 —
nt.send_auth_response()(authenticated hub + push relay):This does two things:
self.send_update(user_id, &data)(notifications.rs:524) — sends via the authenticated WebSocket hub to all devices of the user, including Device B (the approving device).push_auth_response()(notifications.rs:528→push.rs:322) — sends a push notification to all devices of the user via the Bitwarden relay, which also reaches Device B.Both paths in call 2 reach Device B, causing the duplicate notification.
How the official Bitwarden server handles this
Looking at the official server code:
SignalR (
HubHelpers.cs:109-120):AuthRequestResponse(type 16) is sent only through_anonymousHubContexttoGroup(AuthRequest.Id). It is not sent through the authenticated_hubContext. This is the key difference fromAuthRequest(type 15), which uses_hubContext.Clients.User().Push relay (
RelayPushEngine.cs:100): WhenExcludeCurrentContext = true, theIdentifieris set to the acting device's identifier, andNotificationHubPushEnginebuilds an exclusion tag!deviceIdentifier:{identifier}to prevent the push from reaching the approving device.Proposed fix
The simplest fix aligned with the official server behavior would be to remove the
nt.send_auth_response()call entirely, sinceAuthRequestResponseshould only be delivered through the anonymous hub:However, there's a consideration: if Device A is not connected via WebSocket (e.g., a mobile app in background), it won't receive the response through the anonymous hub alone. The push relay would be the fallback for that scenario. A more conservative approach would be to:
I'd appreciate feedback on which approach the maintainers prefer before submitting a PR.
@BlackDex commented on GitHub (Apr 17, 2026):
It looks like Bitwarden Self-Hosted has the same issue, but I can't replicate it on Bitwarden Cloud though.
I have not yet looked deeper into this, that takes some time.