feat(mfa): support multiple users per device for device trust #2360
+158
−19
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
When multiple users trust the same device/browser, the device trust cookie (
hanko-device-token) gets overwritten with each new trust action. This causes previous users to lose their device trust status and be required to re-enter their TOTP code on every login. It's an improvement from initial PR about trust-device implementation (#1982)Reproduction steps:
tokenAtokenBtokenB→ MFA required (trust lost)This is a common scenario in shared environments (family computers, shared workstations, demo environments, etc.) where multiple users need to authenticate from the same browser.
Solution
This PR introduces a composite cookie format that stores multiple user tokens in a single cookie, allowing each user to maintain their own device trust independently.
New cookie format:
Example:
Fixes the device trust overwrite issue for multi-user scenarios.
Implementation
Changes Overview
backend/config/config_mfa.goDeviceTrustMaxUsersPerDeviceconfig fieldbackend/config/config_default.gobackend/flow_api/services/device_trust.gobackend/flow_api/flow/device_trust/hook_issue_trust_device_cookie.godeploy/docker-compose/config.yamlKey Design Decisions
1. Composite Token Format
Chose
<user_id>:<token>|<user_id>:<token>format because:2. Backward Compatibility
The implementation detects and handles legacy single-token cookies:
When a legacy cookie is detected:
3. Entry Management
DeviceTrustMaxUsersPerDevice4. Configuration
New config option with sensible default:
Code Flow
When checking device trust (
CheckDeviceTrust):When issuing trust cookie (
IssueTrustDeviceCookie):Tests
Manual Testing Steps
Setup
Test Case 1: Multi-User Device Trust
hanko-device-tokenshould contain composite format with both user IDsTest Case 2: Legacy Cookie Migration
hanko-device-token=<single_token_value>Test Case 3: Max Users Limit
device_trust_max_users_per_device: 2in configTest Case 4: Malformed Cookie Handling
hanko-device-token=invalid|data|hereAdditional Context
Security Considerations
HttpOnly,Secure,SameSiteprotections unchangedCookie Size Analysis
Browser Compatibility
The composite cookie format uses only standard ASCII characters (alphanumeric,
-,=,|,:) and is compatible with all modern browsers' cookie handling.