-
Notifications
You must be signed in to change notification settings - Fork 7
Identity
Identity is a participant in DataPeps E2EE communication schemes.
An identity can be regarded as a set of cryptography keys (which we further call "identity's keys"), used for E2EE communications. Although multiple keypairs are associated with the identity, the SDK always works with the set of keys in a bulk, so we will refer to the identity's keypairs as to a single keypair.
An identity can create and manage other identities, which allows to control data sharing in a fine-grained manner.
Each identity has a sharing group associated with it, which is a list of identities — sharers — that have some accesses to the identity.
- has access to the identity's resources
- can log in as the identity
- can emit requests on behalf of the identity
Each identity has an access group associated with it, which is a list of identities for which the identity is a sharer.
A sharing graph is a directed graph, in which nodes represent identities and edges represent sharing/access relations between them. If there exists a path from an identity A to an identity B, then A has access to B. Here's an example of such a graph:
images/concepts/identity/users_group.png
Such configuration of identities allows to share resources between multiple identities in a simple way. In the example above Alice and Bob can establish E2EE communications with the AliceFriends identity (Alice and Bob are AliceFriends sharers). All the identities that can access AliceFriends (i.e. Alice and Bob) and Charlie can establish communications with the BobFriends identity (AliceFriends and Charlie are BobFriends sharers).
In a social network, for example, AliceFriends and BobFriends could represent Alice's and Bob's friends respectively, that could share end-to-end encrypted messages, photos, videos, etc., with each other. In this example of the friends of Alice are also the friends of Bob.
Further we'll see how to create such a sharing graph.
A sharer can manage an identity's sharing group. In particular he can:
// Alice adds Bob and Charlie to her sharing group
await new DataPeps.IdentityAPI(aliceSession).extendSharingGroup(aliceGroup, [bob.login, charlie.login])
- replace the sharing group: the existing sharing group is replaced with the given list of identities.
// Charlie is excluded from the Alice's sharing group
await new DataPeps.IdentityAPI(bobSession).replaceSharingGroup(aliceGroup, [alice.login, bob.login])
Identities can also request information on the sharing and access groups of another identity:
let sharingGroup = await aliceSession.Identity.getSharingGroup(aliceGroup)
let accessGroup = await aliceSession.Identity.getAccessGroup(aliceGroup)
To register a new identity, a user provides identity's data and secret (e.g. a password):
let alice = {
login: "[email protected]",
name: "Alice Liddell",
kind: "user",
payload: new TextEncoder().encode(JSON.stringify({
firstname: "Alice",
lastname: "Liddell",
tel: "5552368"
}))
}
let aliceSecret = "aliceP@ssw0rd"
await DataPeps.register(alice, aliceSecret)
This method is reserved primarily for DataPeps administrators, thus the availability of this API endpoint depends on the configuration of the server.
Alice links an email address with the server and requests a registration token:
let aliceEmail: String = "[email protected]"
await sdk.sendRegisterLink(aliceEmail)
The email is now linked with Alice's identity and she will use it as the login.
Alice has received an email with the token and registers herself with the DataPeps service:
let token = "YSBmYW5jeSByZWdpc3RyYXRpb24gdG9rZW4="
let alice = {
login: "[email protected]",
...
}
let aliceSecret: String = "aliceP@ssw0rd"
await sdk.registerWithToken(token, alice, aliceSecret)
Identity creation is different from Identity registration in two ways:
- Users can create identities only after establishing a session with DataPeps;
- A sharing group can be specified for the newly created identity.
Here is an example of an identity creation:
let aliceSession = await DataPeps.login(alice.login, aliceSecret)
let aliceGroup = {
login: "[email protected]",
name: "Alice Group",
kind: "group",
payload: new TextEncoder().encode(JSON.stringify({
description: "This is a group created by [email protected]."
}))
}
await new DataPeps.IdentityAPI(aliceSession).create(aliceGroup, { sharingGroup: [alice.login] })
A client will be able to login as the created identity, if the identity's secret is specified during the creation:
await new DataPeps.IdentityAPI(aliceSession).create(aliceSecond,
{ sharingGroup: [alice.login], secret: "aliceSecondP@ssw0rd" })
An identity's keys are renewed like this:
let session: Peps.Session = await DataPeps.login(aliceSecond.login, aliceSecondSecret)
await session.renewKeys()
If an identity has been created without a secret, i.e. a user cannot log in as the identity, the keys can be renewed as described here.
After establishing a session, identity can fetch its own public key or request public keys of other identities. It is possible to fetch a particular version of the public keys.
DataPeps allows users to verify the validity of the fetched public keys.
In DataPeps an identity is identified by its public key. An identity can get its own public key like this:
let alicePublicKey = await aliceSession.getSessionPublicKey()
The latest version of the identity's public key is retrieved like this:
// for a single key
let bobKey = await aliceSession.getLatestPublicKey("bob")
// for a list of keys
let listOfKeys = await aliceSession.getLatestPublicKeys(["bob", "charlie"])
The identity's public key of a specific version is retrieved like this:
// for a single key
let bobKeyRequest = { login: "bob", version: 3 }
let bobOldKey = await aliceSession.getPublicKey(bobKeyRequest)
// for a list of keys
let charlieKeyRequest = { login: "charlie", version: 2 }
let listOfOldKeys = await aliceSession.getPublicKeys([bobKeyRequest, charlieKeyRequest])
To prevent a Man-in-the-middle attack identities verify the validity of fetched public keys.
By default, the public keys are verified in accordance with the TOFU security model. In short, when an identity receives a public key, he checks it the key is already present in the local keys cache. If it is the case, the user validates the received key with the use of the matching key in the cache. If not, the user trusts the received key and adds it to the cache.
DataPeps SDK allows to change this behavior, see Configuring public keys validation for details.
Identity's registration — an identity registration.
Identities sharing graph creation — an identities sharing graph creation as described above.