Update: This is outdated. I posted a simpler solution here: Improved privacy, social recovery for apps, no need for contexts
There is a potential privacy concern when a BrightID node operator has access to the contextIds of users in multiple application contexts and also has a mapping of contextIds to profile information of those users. This could occur if the node operator is also an adminstrator of several applications, or if there has been a data leak in an application. Such an operator could create unwanted linkage of profile data: for example, that user X of chat application A is also user Y of financial application B.
Using blind signatures, we can have a system where even if a node operator and an app admin are the same, there will be no linkage between a BrightID and contextId, yet users identified by a contextId can still be verified as unique.
A solution is also presented to use BrightID’s social recovery to recover access to any application that uses BrightID.
A user commits to a contextId in a context; this is usually a self-generated unique identifier (for example, an Ethereum address). This commitment is then presented to a node as a blinded message along with a BrightID and an application name. It’s shared in that format as a BrightID node “operation.” A node processing the operation checks that the BrightID is verified as unique according to the requirements for the named application, and if so, increments a counter for the BrightID in that context. The node serving the original request then blindly signs the message and attaches the counter value and application name. Because the message was blinded, node operators don’t ever see the contextId.
The user then delivers the signed message to the application. The application opens the message and reads the application name, contextId and counter value, but it can’t see which BrightID is associated with the user. Usages of the counter value are described below.
Verification expiration and contextId rotation
BrightID nodes don’t attach timestamps to the signed messages because these could be used to match a contextId to a BrightID. An application can instead record the fact that a contextId appeared in a signed message and disallow its reuse.
If verifications are allowed to expire (which is recommended for applications that involve more than a one-time interaction), the user should generate a new contextId when the current one expires and register it with the application (which creates a link in the application to the previously used contextId). The application should remember how many contextIds a user has registered. This can be compared to the counter value returned in the signed message. A counter value that is larger or smaller than expected could indicate a sybil attack and should disqualify the user.
Losing access to an application
A user that loses access to a contextId for an application–exhausting any recovery methods provided by that application–will be left in a situation where they can’t register a new contextId and link it to the previous one.
Restoring access through social recovery
Within an hour of social recovery, a user can ask a node to re-sign any previous blinded message, adding a new ephemeral public key submitted by the user. (This is also blinded to prevent unwanted linkages of contextIds and BrightIDs).
An application should accept any such signed message, and subsequently allow the user delivering it to register a new contextId after proving ownership of the ephemeral key. The new contextId will then be blinded and submitted to a BrightID node to be signed as usual, allowing the user to regain access to the application.
ContextIds must be unique
An application must not register a contextId that has been registered before as this could be used to hijack another user’s account through social recovery.
Avoiding accidental resubmission of a contextId
BrightID nodes can store blinded messages and reject ones they have seen previously to avoid incrementing a counter inappropriately.
Avoiding linkage through timing
Clients can wait a random amount of time to send signed messages to applications to avoid the linkage of BrightIDs to contextIds by node operators that also serve as application administrators.