# Integrate 2-man-rule on your backend

As explained in the identity management guide, protection with 2-man rule requires some modifications on your backend.

More precisely, two things need to be modified:

  • the generation and storage of a secret twoManRuleKey key associated to a user of your application, which can be retrieved when authenticated;
  • an interaction with the Seald Secure Key Storage (SSKS) service so that the user can authenticate to SSKS.

We note:

  • User: the user of the application whose identity is to be protected;
  • Identity: a Seald cryptographic identity of the User (described in the dedicated guide);
  • Frontend: the frontend of the application in which the SDK is integrated;
  • Backend: the backend of the application in which the SDK is integrated, it will store twoManRuleKey, the key to decrypt encryptedIdentity;
  • SSKS: an instance of Seald Secure Key Storage, it will store encryptedIdentity, not decryptable without the twoManRuleKey.

The goal is to give the User the two "pieces" of his Seald identity ( twoManRuleKey and encryptedIdentity) by authentication, while preventing SSKS and the Backend from being able to independently access the user's identity.

# Requirements

To communicate with the SSKS server, your Backend will need:

  • the SSKS server URL: the default shared instance is https://ssks.seald.io/;
  • ssksAppId: corresponds to the appId used in the SDK;
  • ssksAppKey: allows your Backend to authenticate itself to the SSKS server.

This ssksAppKey can be generated or renewed on the administration dashboard.

Go to the SDK management page
1. Go to the SDK management page
Generating the key
2. In the "SSKS-2MR backend key" section, click on the "Generate a key" button
Key generated
3. You can copy the generated key. Warning, you will not have access to it later! Save it now!

# Protocol

The protocol is carried out in two steps:

  1. initial identity protection, which normally occurs only once immediately after generation;
  2. identity recovery, which happens every time the User wants to recover his identity locally.

TIP

The protection of an identity in 2-man rule is usually coupled with a persistent local database to "cache" the identity of the User, and avoid the need to retrieve it each time he opens the application.

The protocol for performing the initial protection of a User's identity is as follows:

uml diagram

TIP

In the case where an identity has previously been stored onto SSKS with the same email address, the SSKS server will then demand an authentication with an email challenge, by sending mustAuthenticate at true.

In this case, the user will receive a challenge valid for 6h by email, and they will need to repeat this code into the front-end in order to be able to authenticate on SSKS before being able to store their new identity.

To retrieve the identity of this User in another session, the protocol is as follows:

uml diagram

The red arrows in the diagram indicate the operations to be implemented in the application that uses the Seald SDK and the 2-man rule protection mode. The black arrows indicate what is already implemented by the SDK, the 2-man rule protection plugin @seald-io/sdk-plugin-ssks-2mr or SSKS.

# Identity protection

Before calling the saveIdentity method exposed by the plugin @seald-io/sdk-plugin-ssks-2mr, you need the following elements:

  • userId: a unique identifier of the user in the application;
  • email: user's email address used for challenge authentication, must be repeated or verified by the user to ensure that the backend is not trying to perform an MITM attack (opens new window);
  • twoManRuleKey: the key known by the backend allowing to encrypt / decrypt the identity;
  • sessionId: the session identifier generated by SSKS and transmitted by the backend to the SDK;
  • if the server sent mustAuthenticate at true, challenge: a random token sent by SSKS by email to the user to authenticate them, valid for 6h, never to be revealed to the backend;

To do this, we need to implement an authenticated getSSKSSession API point on the backend that:

  1. uses the API endpoint POST https://{SSKS_URL}/tmr/back/challenge_send/ to send to SSKS:
  • create_user: set it at true to create the user on SSKS in the same request, otherwise you'll need to make another request before ;

  • user_id: is the userId in @seald-io/sdk-plugin-ssks-2mr;

  • email: the user's e-mail address to which the challenge will be sent;

  • template: the email template to be used in HTML format, and which must contain $$CHALLENGE$$ which will be replaced by the challenge.

    SSKS will return to the backend sessionId and mustAuthenticate.

    If mustAuthenticate is true, SSKS will send an email in template format to the email address containing challenge, valid for 6h;

  1. generates twoManRuleKey (64 cryptographically robust random bytes) and stores it associated with this user;
  2. returns to the frontend sessionId and twoManRuleKey.

TIP

In the case where mustAuthenticate is true, the frontend must block and wait for the user to enter the challenge which was sent to them by email before calling the method saveIdentity.

In the case where mustAuthenticate is false, the frontend can call the method saveIdentity directly.

Then the frontend can use the method saveIdentity as follows:

TIP

For optimal security, it is recommended to display in frontend the email address that is about to be sent to SSKS before calling saveIdentity, in order to make sure the backend has indeed created the SSKS user with the correct email address, and that we are about to store the user's identity linked to an email address they control.

# Identity retrieval

Before calling the retrieveIdentity method exposed by the @seald-io/sdk- plugin-ssks-2mr plugin, you need the same elements as for the saveIdentity method described in the previous paragraph.

To do this, we reuse the same getSSKSSession point described in the previous section, except that it does not generate a new twoManRuleKey but returns the one already generated:

  1. uses the API endpoint POST https://{SSKS_URL}/tmr/back/challenge_send/ to send to SSKS:
  • create_user: set it at False, at this step, the user should already be created on SSKS;

  • user_id: is the userId in @seald-io/sdk-plugin-ssks-2mr;

  • email: the user's e-mail address to which the challenge will be sent;

  • template: the email template to be used in HTML format, and which must contain $$CHALLENGE$$ which will be replaced by the challenge.

    SSKS will send an email in template format to the email address containing challenge, valid for 6h, and return the backend sessionId;

  1. retrieves the twoManRuleKey associated with this user;
  2. returns to the frontend sessionId and twoManRuleKey.

Then the frontend can use the method retrieveIdentity as follows:

# Security

The security of such a protocol is based on:

  1. Secure storage of at least one piece of the identity: unlike storage at a single trusted third party (digital safe, KMS, Cloud HSM, ...), this protocol is robust to partial breach. One would have to breach both the Backend and SSKS simultaneously to breach the users' identities.
  2. Authentication independence: SSKS and the Backend must not rely on the same authentication protocols. If both use the same SSO for example, then only the SSO server has to be malicious to completely breach the security of the protocol. The same applies to social logins.
  3. Non-collusion of servers: it is necessary that SSKS and the Backend cannot have access to the other secret, and especially not by API, otherwise breaching one server would be enough to get both secrets.
  4. the secure "splitting" of the identity: the protocol chosen by Seald to "split" the identity ensures that knowing a "piece" does not accelerate a brute force attack, contrary to a naive slicing of a string in two.

The limitations of this protocol are:

  1. if both protocols use the same factors to authenticate the user (e.g., email), then breaching the user's factors is sufficient to breach the identity (as with SSO).
  2. If SSKS and the Backend were breached (or subpoenaed) simultaneously, the users' identities could be reconstructed by the attacker.

WARNING

This protocol is not strictly "end-to-end", in the sense that the users' identities can be reconstructed without their intervention or the intervention of their devices.

# Examples

The functions to be implemented being relatively simple, and their implementation varying considerably from one backend technology to another, we do not provide a library implementing these functions.

On the other hand, this part gathers several examples of implementation in several languages.

# PHP (vanilla)

get_ssks_session.php:

# Python (django)

views.py: