-
Notifications
You must be signed in to change notification settings - Fork 19
BrightID Node v6 Changelog
This document explains the new features and updates in the BrightID Node API v6.
There used to be a potential privacy concern when a BrightID node operator had access to the mapping of contextIds to brightids of users. By using blind signatures there is no linkage between brightids and contextIds on nodes anymore, although users identified by an appId can still be verified as unique.
In this new approach, clients generate a unique id per app, blind it and send it to the node to be signed. Nodes check if they did not sign a request for this user for this app before, sign the blinded id and deliver the signature to the client.
To enable apps that can not verify blind signatures (like Ethereum smart contracts) to use this new approach, and keep the app integration routine as simple as before, apps generate and share another id called appIds via deep links with clients just like before and clients put these app-generated appIds with the blind signatures they got before to the node, nodes verify the signatures without knowing which brightid they belong to, and enable apps to query verification by their own generated appId.
Partially blind WI-Schnorr signature scheme is used to implement this new app integration approach as follow:
As soon as users achieve apps' required verifications, the client automatically gets the public part of WI-Schnorr params by sending JSON representation of {app, roundedTimestamp, verification}
as info
to the node by calling GET /verifications/blinded/public
.
Query parameter | R / O | Description | Data type |
---|---|---|---|
app | Required | unique app id | string |
roundedTimestamp | Required | timestamp that is rounded to app's required precision or zero | integer |
verification | Required | verification expression | string |
Response item | Description | Data type |
---|---|---|
public | public part of WI-Schnorr params that should be used to generate challenge | string |
Applications may have an expiration period to enforce users to renew their verification by getting new blind signatures in each period. roundedTimestamp
is the current timestamp that is rounded to the app's required precision and added to the info
to enable clients to get a new signature in each period.
When the client gets the public part of WI-Schnorr (response of step 1), it creates a challenge and queries GET /verifications/blinded/sig/{id}
to get the blinded form of signature which will be used by the client to generate the final unblinded signature.
Path parameter | R / O | Description | Data type |
---|---|---|---|
id | Required | the brightid of the user requesting the verification | string |
Query parameter | R / O | Description | Data type |
---|---|---|---|
public | Required | public part of WI-Schnorr params | string |
sig | Required | representation of {id, public} signed by the user | integer |
e | Required | the e part of WI-Schnorr challenge generated by client | string |
Response item | Description | Data type |
---|---|---|
response | WI-Schnorr server response that will be used by the client to generate final signature | string |
When a user wants to use an app, the app generates and shares an appId with the client. The client asks the node to link the client-generated uid in the past with the app-generated appId using the POST /verifications/{app}/{appId}
endpoint.
Path parameter | R / O | Description | Data type |
---|---|---|---|
app | Required | the app that user is verified for | string |
appId | Required | the id of the user within the app | string |
Body parameter | R / O | Description | Data type |
---|---|---|---|
sig | Required | unblinded sig | object |
verification | Required | verification required for using the app | string |
roundedTimestamp | Required | timestamp that is rounded to app's required precision or zero | integer |
uid | Required | uid generated by the client per app per expiration period | string |
There is no linkage between the brightid and the uid because the node singed blinded representation of the uid in the previous step. So linking appId with uid in this step will not reveal the brightid of the verified user for the node operator.
Apps can use GET /verifications/{app}/{appId}
to query all signed verifications for the user using app-generated appId as the identifier from the node.
Path parameter | R / O | Description | Data type |
---|---|---|---|
app | Required | the app that user is verified for | string |
appId | Required | the id of the user within the app | string |
Query parameter | R / O | Description | Data type |
---|---|---|---|
signed | Required | the value will be eth or nacl to indicate the type of signature returned | string |
timestamp | Required | request a timestamp of the specified format to be added to the response | integer |
In v6 apps can define multiple verifications that they want and querying this endpoint returns a list of signed verification objects with the following pattern:
Response item | Description | Data type |
---|---|---|
unique | true if user is unique under given app | boolean |
app | unique id of the app | string |
appId | the id of the user within the app | string |
verification | verification expression | string |
verificationHash | sha256 of the verification expression | string |
timestamp | timestamp of the verification if a timestamp was requested | string |
sig | verification message signed by the node | string |
publicKey | the node's public key | string |
In this new approach, clients generate a message with the brightid, blind and share it with the apps to be signed. Apps sign the blinded message and send it to the clients to sponsor users. Clients unblind the signature and send the Sponsor
operation with unblinded apps' signature.
Chaum's blind signature scheme is used to implement this new approach as follow:
Property | Description |
---|---|
id | the brightid of the user that is being sponsored |
app | the app name that the user is being sponsored by |
sig | unblinded signature of Chaum's blind signature schema using deterministic json representation of {name: 'Sponsor', id, app, timestamp, v: 6} as message |
Family groups are introduced in version 6 as a new type of group.
Each user is allowed to be a member of at most one family group and be the head of some other family groups. Only parents and siblings can be members of the family group. Users can join a family group only if they have "already known" or stronger connection levels with all current members of the group. Outside users which have "already known" or stronger connection level with all members of a family group can vouch for the family group. These users get notifications on their clients to vouch for groups they already know all of their members after the head set.
Vouches to the family groups can be considered as a strong connection from vouchers to all of the group members. This type of connection is one-way, trust flows from the outside person to the members of the family group.
The concept of a "Family Group" can help to solve the small-scale Sybil attack problem. small-scale Sybil attacks become much less likely as long as honest users understand the rules of family groups.
Users can create a family group using the Add Group
operation and setting family
as type
.
Admins can set/change the head of the family groups using the Set Family Head
operation.
Property | Description |
---|---|
id | the brightid of one of the current admins of the group |
head | the brightid of the member who will be the new head |
group | the unique id of the family group |
sig | representation of operation object signed by admin represented by id |
Admins can convert general groups to family groups using the Convert To Family
operation.
Property | Description |
---|---|
id | the brightid of one of the current admins of the group |
head | the brightid of the member who will be the head |
group | the unique id of the group |
sig | representation of operation object signed by admin represented by id |
Eligible users can vouch for a family group using the Vouch Family
operation.
Property | Description |
---|---|
id | the brightid of the user who is vouching for the family group |
group | the unique id of the group |
sig | representation of operation object signed by the head user represented by id |
Clients can use GET /users/{id}/familiesToVouch
to get a list of family groups that users can vouch for and notify them to evaluate the groups and vouch for them.
Path parameter | R / O | Description | Data type |
---|---|---|---|
id | Required | the brightid of the user | string |
Response item | Description | Data type |
---|---|---|
families | list of family groups which the user can vouch for | array |
In version 6, users can create groups independently and groups do not need to have 3 founders. The creator of the group should be able to invite as many users as he/she wishes to the group after choosing the group name, photo, and type in the early founding stage.
Based on this update, id2
, id3
, inviteData2
and inviteData3
properties are removed from Add Group
operation.
Property | Description |
---|---|
group | the unique id of the group |
id | brightid of the first founder |
url | the URL that group data (profile image and name) encrypted by group AES key can be fetched from |
type | type of the group |
sig | representation of operation object signed by the creator of the group represented by id1 |
The GET /users/{id}
is deprecated and independent sub-endpoints are added to query different information about users.
Group memberships of a user can not be accessed from the groups
property of the old general endpoint anymore and clients should query GET /users/{id}/memberships
to get this information.
Path parameter | R / O | Description | Data type |
---|---|---|---|
id | Required | the brightid of the user | string |
The response is an array of memberships with the following properties:
membership property | Description | Data type |
---|---|---|
id | the id of the group | array |
timestamp | the timestamp when user joined the group | array |
Invites of a user can be queried using GET /users/{id}/invites
.
Path parameter | R / O | Description | Data type |
---|---|---|---|
id | Required | the brightid of the user | string |
The response is a list of invites with the following properties:
invites property | Description | Data type |
---|---|---|
inviter | brightid of the admin of the group | string |
invitee | brightid of the user who is invited to the group | string |
group | the unique id of the group that invitee is being invited to | string |
data | the group AES key encrypted for signingKey of the invitee | string |
sig | epresentation of operation object signed by the inviter | string |
reportReason
is added to the connection objects in response of GET /users/{id}/connections/{direction}
.
In version 6, the response of querying GET /users/{id}/profile/{requestor}
is changed.
-
reports
are changed and have the following properties:report property Description id brightid of the reporter reason the reason for reporting (spammer, fake, duplicate, deceased, replaced, other) -
sponsored
is added to the response to show if a user is sponsored. -
recoveryConnections
is added to the response with the following properties:recoveryConnection property Description id brightid of recovery connection isActive true if recovery connection active now activeAfter milliseconds until activation activeBefore milliseconds until inactivation Adding recovery connections to this endpoint enables clients to show the list of recovery connections of users' connections in the profile screen of each connection beside mutual connections and groups. This enables users to ask their friends who are recovery connections of them when they forget that. Also adding
activeAfter
andactiveBefore
properties enables clients to show when a recovery connection will be activated or become inactive. Clients can use this endpoint to show the list of recovery connections either for users themselves or for their connections.
In version 6, the response object of querying GET /groups/{id}
is changed.
eligibles
, founders
and isNew
properties are deprecated and removed. invites
also changed to have the following properties:
invite property | Description |
---|---|
id | unique identifier of invite |
group | unique identifier of the group that invitee is invited to |
inviter | brightid of inviter |
invitee | brightid of invitee |
timestamp | timestamp when the user was invited |
data | encrypted version of the AES key that group name and photo uploaded to url encrypted with' + 'invitee should first decrypt this data with his/her signingKey and then fetch data in url and decrypt that using the AES key' |
In version 6, the following properties are added to the response object of GET /apps/{app}
and GET /apps
:
-
verifications
is a list of verifications that apps use. -
idsAsHex
is true if app ids are in Ethereum address format. -
usingBlindSig
is true if the app is using blind signatures. -
verificationExpirationLength
is the apps' verification expiration length in milliseconds. -
sponsorPublicKey
is the public part of the key pair that the app uses to sign sponsor requests. -
nodeUrl
is the URL of the node that the app uses to query verification from.
-
Add Connection
is deprecated andConnect
can be used instead. -
Remove Connection
is deprecated andConnect
can be used withreported
level instead. -
Set Trusted Connections
is deprecated andConnect
can be used withrecovery
level instead. -
Set Signing Key
is renamed toSocial Recovery
. -
Link ContextId
is deprecated.
-
GET /verifications/{app}
is deprecated. -
PUT /testblocks/{app}/{action}/{contextId}
is deprecated. -
DELETE /testblocks/{app}/{action}/{contextId}
is deprecated. -
GET /contexts/{context}/dump
is deprecated. -
GET /ip
is deprecated.