TMR Accesses
Le concept des TmrAccesses
est une fonctionnalité du SDK Seald qui permet de récupérer une EncryptionSession
par un mécanisme de 2-man rule, comme pour le stockage des identités.
L'idée est de protéger une EncryptionSession
pour un certain Auth Factor (une adresse email, ou un numéro de téléphone), avec une certaine overEncryptionKey
qui sera stockée par vos serveurs (comme la twoManRuleKey
pour le stockage des identités).
Ensuite, lorsqu'il veut la récupérer, le destinataire reçoit un challenge
par email ou SMS, valable 6h, et doit le répéter dans l'application pour prouver qu'il maitrise le Auth Factor, et peut accéder à la EncryptionSession
.
Cette fonctionnalité est particulièrement utile pour ajouter comme destinataire à une EncryptionSession
un utilisateur qui n'est pas encore inscrit sur votre application, par exemple au moment de lui envoyer une invitation.
Création d'un TmrAccess
L'utilisateur qui a créé une EncryptionSession
, ou tout utilisateur y ayant accès et qui a le droit forward
, peut créer un TmrAccess
pour cette EncryptionSession
.
Pour créer un TmrAccess
, il faut récupérer l'objet EncryptionSession
, et utiliser la méthode session.addTmrAccess()
. Cette méthode prend comme argument tmrRecipients
, qui est un Array
de TmrRecipientWithRights
. Chaque élément de cet Array
contient trois champs :
authFactor
, qui lui même contient le type de l'Auth Factor utilisé ('EM'
pour une adresse email,'SMS'
pour un numéro de téléphone), et la valeur de cet Auth Factor ;rawOverEncryptionKey
, qui est la clé à utiliser pour protéger ceTmrAccess
, doit absolument être l'encodage en base64 d'un buffer cryptographiquement aléatoire de 64 octets ;- optionnellement,
rights
qui définit les droits pour ceTmrAccess
.
TIP
Afin d'assurer la confidentialité end-to-end, la rawOverEncryptionKey
doit n'être accessible qu'à la personne qui crée le TmrAccess
et au destinataire de la session.
Il est de la responsabilité de votre serveur de stocker ces rawOverEncryptionKey
et d'en limiter l'accès à l'utilisateur qui crée le TmrAccess
et l'utilisateur invité.
Si plusieurs utilisateurs doivent ajouter des TmrAccesses
à destination du même Auth Factor, il convient de créer des rawOverEncryptionKey
s différentes pour chacun. Vous pouvez également créer une rawOverEncryptionKey
différente pour chaque ajout de TmrAccess
, même si c'est le même utilisateur qui l'ajoute pour le même Auth Factor, si cela est plus simple pour vous.
Vous pouvez également spécifier des droits pour le destinataire de ce TmrAccess
avec l'argument rights
. Lorsque l'utilisateur convertit un TmrAccess
en accès normal, ces droits seront convertis avec.
TIP
Les rights
par défaut pour un TmrAccess
sont { read: true, forward: true, revoke: false }
.
La méthode session.addTmrAccess()
rend l'ID du TmrAccess
créé. Cet ID n'est pas secret, et peut être transmis à votre serveur. Il peut servir à administrer le TmrAccess
, ou encore à choisir quel TmrAccess
utiliser pour récupérer une session.
Exemple d'utilisation :
// Chaque `rawOverEncryptionKey` doit nécessairement être un buffer de 64 octets aléatoires cryptographiquement sécurisé, encodé en base64.
const rawOverEncryptionKey = await sealdSdk.utils.generateB64EncodedSymKey()
// Création des `TmrAccess`
const tmrAccessId = await session.addTmrAccess({
authFactor: { type: 'EM', value: 'test@example.com' },
rawOverEncryptionKey,
rights: { read: true, forward: false, revoke: false }
})
// Maintenant, vous pouvez envoyer le tmrAccessId avec la rawOverEncryptionKey à vos serveurs pour les enregistrer.
TIP
Si vous avez besoin d'ajouter plusieurs TmrAccesses
à la même EncryptionSession
, pour plusieurs Auth Factors destinataires par exemple, vous pouvez également utiliser la méthode session.addMultipleTmrAccesses()
. Celle-ci à un type de retour plus complexe, détaillé dans sa référence.
Récupération d'une session avec un TmrAccess
Pour récupérer une EncryptionSession
via un TmrAccess
, il faut d'abord prouver que l'on contrôle le Auth Factor destinataire de celui-ci. Pour ceci, il faut récupérer un JWT depuis le serveur SSKS avec la méthode ssks2MR.getFactorToken()
. Cette méthode nécessite bien entendu d'être authentifié auprès de SSKS, c'est-à-dire soit d'avoir déjà un authenticatedSessionId
, soit d'utiliser le point d'API POST /tmr/back/challenge_send/
(avec force_auth
à true
) pour obtenir un challenge, et passer ce challenge lors de l'appel à ssks2MR.getFactorToken()
.
Ensuite, une fois qu'on a ce token, il faut utiliser la méthode sdk.retrieveEncryptionSessionByTmr()
. Cette méthode prend comme arguments :
- l'ID de l'
EncryptionSession
; - le token rendu par
ssks2MR.getFactorToken()
; - la
rawOverEncryptionKey
utilisée ; - optionnellement, des options (notamment de filtrage) détaillées plus bas.
La méthode sdk.retrieveEncryptionSessionByTmr()
rend une EncryptionSession
, qui permet ensuite de chiffrer/déchiffrer des messages et fichiers.
TIP
Si vous accédez à une EncryptionSession
via un TmrAccess
, vous ne pouvez pas utiliser les méthodes de gestions d'accès de celle-ci (session.addRecipients()
, session.addSymEncKey()
, session.revokeRecipients()
, session.listRecipients()
, ...) sans l'avoir convertie.
Exemple d'utilisation simple :
// Récupération d'un tmrJWT
const getFactorTokenResponse = await sdk.ssks2MR.getFactorToken({ sessionId: ssksSessionId, authFactor, challenge })
// Récupération d'une EncryptionSession avec un `TmrAccess`
const encryptionSession = await sdk.retrieveEncryptionSessionByTmr(
encryptionSessionId, // `encryptionSessionId` n'est pas secret, et peut être transmis via votre serveur
getFactorTokenResponse.token, // Le token obtenu par l'appel de `ssks2MR.getFactorToken()`
rawOverEncryptionKey // `rawOverEncryptionKey` transmis par votre serveur
)
Attention, si il existe plusieurs TmrAccesses
pour le même Auth Factor et la même EncryptionSession
, par défaut retrieveEncryptionSessionByTmr()
renverra une erreur. En effet, cette fonction doit savoir quel TmrAccess
utiliser, c'est-à-dire lequel correspond à la rawOverEncryptionKey
passée.
Pour cela, retrieveEncryptionSessionByTmr()
accepte un objet d'options, qui contient les options facultatives suivantes :
useCache
: un booléen, qui est par défaut àtrue
. Indique d'essayer de récupérer la session dans le cache ;tmrAccessId
: l'ID duTmrAccess
à utiliser. Si vous l'avez, il est recommandé de le passer systématiquement, pour éviter tout problème ;createdById
: l'ID de l'utilisateur qui a ajouté leTmrAccess
à utiliser ;tryIfMultiple
: un booléen, qui est par défaut àfalse
. Si mis àtrue
, et si les autres filtres éventuels passés correspondent à plusieursTmrAccesses
, indique d'itérer sur tous lesTmrAccesses
récupérés pour trouver sur lequel larawOverEncryptionKey
passée fonctionne, au lieu de renvoyer une erreur.
Exemple d'utilisation avec options :
// Récupération d'un tmrJWT
const getFactorTokenResponse = await sdk.ssks2MR.getFactorToken({ sessionId: ssksSessionId, authFactor, challenge })
// Récupération d'une EncryptionSession avec un `TmrAccess`
const encryptionSession = await sdk.retrieveEncryptionSessionByTmr(
encryptionSessionId, // `encryptionSessionId` n'est pas secret, et peut être transmis via votre serveur
getFactorTokenResponse.token, // Le token obtenu par l'appel de `ssks2MR.getFactorToken()`
rawOverEncryptionKey, // `rawOverEncryptionKey` transmis par votre serveur
{
tmrAccessId // récupère la session via le TmrAccess qui correspond à cet ID
}
)
Convertir des TmrAccesses
en accès normaux
Vous pouvez aussi convertir un TmrAccess
en accès normal à l'EncryptionSession
correspondante. Ce mécanisme peut être utile si le TmrAccess
a été créé en tant qu'invitation d'un utilisateur qui n'a pas encore de compte Seald à accéder à une EncryptionSession
. Une fois que celui-ci a créé son compte Seald, les TmrAccesses
lui étant destinés peuvent être convertis en accès normaux, pour que son compte Seald puisse à l'avenir accéder aux EncryptionSessions
correspondantes sans passer par une authentification 2-Man-Rule à chaque fois.
Afin de convertir un TmrAccess
en accès normal à l'EncryptionSession
, il faut d'abord prouver que l'on contrôle le Auth Factor destinataire de celui-ci. Pour ceci, il faut récupérer un JWT depuis le serveur SSKS avec la méthode ssks2MR.getFactorToken()
. Cette méthode nécessite bien entendu d'être authentifié auprès de SSKS, c'est à dire soit d'avoir déjà un authenticatedSessionId
, soit d'utiliser le point d'API POST /tmr/back/challenge_send/
(avec force_auth
à true
) pour obtenir un challenge, et passer ce challenge lors de l'appel à ssks2MR.getFactorToken()
.
Ensuite, une fois qu'on a ce token, il faut utiliser la méthode sdk.convertTmrAccesses()
. Cette méthode prend comme arguments :
- le token rendu par
ssks2MR.getFactorToken()
; - la
rawOverEncryptionKey
utilisée ; - optionnellement, des options (notamment de filtrage) détaillées plus bas.
Cette méthode récupère tous les TmrAccesses
correspondants aux filtres données, et les convertit en accès normal à l'EncryptionSession
correspondante.
WARNING
Attention, il faut absolument que tous les TmrAccesses
qui correspondent à ces filtres soient protégés par la même rawOverEncryptionKey
!
Pour cela, convertTmrAccesses()
accepte un objet d'options, qui contient les options facultatives suivantes :
deleteOnConvert
: un booléen, qui est par défaut àtrue
. Indique de supprimer lesTmrAccesses
après leur conversion en accès normaux ;sessionId
: l'ID de l'EncryptionSession
pour laquelle convertir unTmrAccess
;tmrAccessId
: l'ID duTmrAccess
à convertir ;createdById
: l'ID de l'utilisateur qui a ajouté lesTmrAccesses
à convertir.
TIP
Puisqu'il est recommandé d'avoir une rawOverEncryptionKey
différente pour chaque émetteur, et que l'appel à convertTmrAccesses()
doit absolument contenir des filtres qui le limitent à des TmrAccesses
ayant la même rawOverEncryptionKey
, il est recommandé de toujours spécifier createdById
.
Exemple d'utilisation :
// Récupération d'un tmrJWT
const getFactorTokenResponse = await sdk.ssks2MR.getFactorToken({ sessionId: ssksSessionId, authFactor, challenge })
// Conversion des TmrAccesses
const result = await sdk.convertTmrAccesses(
getFactorTokenResponse.token, // Le token obtenu par l'appel de `ssks2MR.getFactorToken()`
rawOverEncryptionKey, // `rawOverEncryptionKey` transmis par votre serveur
{
createdById, // convertit seulement les TmrAccesses créées par l'utilisateur correspondant à ce sealdID
sessionId: encryptionSessionId // convertit seulement les TmrAccesses correspondant à cette EncryptionSession
}
)
// On peut ici vérifier `result` pour vérifier si la conversion a réussi
// Maintenant, l'utilisateur peut récupérer la session directement
const encryptionSession = await sdk.retrieveEncryptionSession({ sessionId: encryptionSessionId })