# Legal hold _Author: Tiago Loureiro_ --- Legal hold introduces a new type of device, named _legal hold device_, for the sake of satisfying corporate compliance rules without sacrificing end to end encryption with full transparency. A _legal hold device_ is a device bound to a team user account but managed outside of the user's control - this is managed by the Legal hold service. The management/operation of said Legal hold service is of the responsibility of the team. This Backend service makes this type of device available for clients that are visually distinguishable, for full transparency, with a clear, constant indication on the UI. There can be only one such device per user account and they can only be added to the user's device list with the user's consent and confirmed with a password prompt (if they have one - there can be exceptions such as SSO users). A team admin may ask members of the team to be put under [legal hold](https://en.wikipedia.org/wiki/Legal_hold). Once a person is prompted, they should then verify that the presented signature matches the one generated by the legalhold service to avoid any potential [MITM attack](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). Conceptually, there are the following actors in this use case: * A team admin - someone who requests legal hold for a specific user * A team member - the user who will be put under legal hold * Backend - serves as intermediary between team members/admin and the Legal hold Service * Legal hold service - stores users' Legal hold devices on customers' premises * Legal hold device - a user's device that is managed by customers Once a user accepts the legal hold request, then a device is added to that user's account. This device, also known as legal hold device, is managed by the Legal hold service - only team admins can remove that device from a user's account. Note that every user talking to someone under legal hold (including, of course, the _self_ user) is made aware by means of displaying a red dot on the user's profile. ## API and flows Legal hold flow (client perspective) Request (by admin) for a user to be put under legalhold ``` POST /teams/{tid}/legalhold/{uid} ``` ``` 201 Created ``` Approval by the user ``` PUT /teams/{tid}/legalhold/{uid}/approve { "password": # optional if the user has no set password } ``` ``` 200 OK ``` Deletion by an admin ``` DELETE /teams/{tid}/legalhold/{uid} { "password": # optional if the admin has no set password } ``` ``` 200 OK ``` Get Legal hold status for team members ``` GET /team/{tid}/members ``` ``` 200 OK ... { "members": [{ "user": member used id, ... "legalhold_status": "disabled" | "enabled", <-- new field ... } } ``` ![LHFlow](https://user-images.githubusercontent.com/1105323/61390098-6bf34800-a8ba-11e9-8ba7-e0759b22a773.png)
title: Legal Hold Flow (client perspective) =: Activation Admin Panel -> Backend: Activate LH for Alice Backend -> LegalHold Service: Request to create Cryptobox for Alice (does NOT include scoped token) LegalHold Service --> Backend: Respond with Public Key etc. for Device Backend -> Admin Panel: LH for Alice is PENDING Backend --> Alice's Client: (Async) Request Approval for LH (includes device fingerprint) Alice's Client -> Backend: Alice APPROVES LH Backend -> LegalHold Service: Send scoped access_token Backend -> Backend: Add Compliance Device to Alice Backend -> Admin Panel: LH for Alice is ACTIVE =: Deactivation Admin Panel -> Backend: Deactivate LH for Alice Backend -> Backend: Remove Compliance Device from Alice; revoke access token.
## Events New legalhold request event: ``` { "type": "user.legalhold-request" , "id": UserID of the one for whom LH is being requested , "last_prekey": Last-prekey of the legal hold device , "client": {"id": Client ID of the legalhold device} } ``` New legalhold enabled event: ``` { "type": "user.legalhold-enable" , "id": UserID for whom LH was enabled } ``` New legalhold disabled event: ``` { "type": "user.legalhold-disable" , "id": UserID for whom LH was disabled } ``` These events are sent to the user, all team members (including admins) and connections. ## Whitelisting and implicit consent This release introduces a notion of intial "consent" to legalhold (LH): In addition to the popup before getting exposed to LH devices (either by getting assigned one or by entering a conversation or connection with one present), users needs to grant their consent to even have the option of being exposed. Until they do, they may be blocked from using wire by their team admin (if they are a team user), but they cannot be assigned a LH device, and they cannot enter conversations with LH devices present. For now, there isn't any UI for the user to grant their initial consent. Instead, an "implict consent" can be given by the site operator by setting ```yaml featureFlags: # [...] legalhold: whitelist-teams-and-implicit-consent ``` in galley's config and then using non-exposed, internal endpoints on the galley pod to update the set of teams whose users are considered to have given their initial consent: - `put /i/legalhold/whitelisted-teams/:team-id` - Add team - `delete /i/legalhold/whitelisted-teams/:team-id` - Remove team - `get /i/legalhold/whitelisted-teams` - List all teams Since consent is required for LH to work, users in teams that are not whitelisted cannot be assigned LH devices (pull request #1502), and they are blocked or removed from conversations that are exposed to LH devices (#1507, #1595). ### Implementation status and future work The notion of consent is introduced to make it explicit, ie. users would have UI components to grant consent themselves, and there would be clear feedback in situations where communication is blocked for lack of consent, so that these situations can be resolved offline. Whitelisting and implicit consent is a short cut. The server side already implements granting explicit consent, but until the UI is ready, site operators have the option of allowing LH to function on a fixed set of teams.