Amazon Cognito: User Pool ou Identity Pool, que choisir ?

Si vous vous lancez sur Amazon Cognito pour la première fois, vous avez dû remarquer que ce service est en réalité composé de deux sous-services : User Pools (groupes d’utilisateurs) et Identity Pools (groupes d’identité), appelé également Federated Identities (Identités Fédérées).

J’étais débutant sur AWS et je souhaitais sécuriser une API Gateway avec une connexion via Google. Cependant, j’avais l’impression que les deux services répondaient à mon besoin. Je ne savais donc pas lequel choisir.

Par la suite j’ai pu découvrir que, même s’ils ont des similitudes, ils ne répondent pas aux mêmes cas d’utilisation. Nous allons voir dans cet article ce qu’ils apportent et dans quelles situations les utiliser.

TL;DR : User Pools vous permet d’ajouter des fonctionnalités d’inscription et de connexion à votre application tandis que Identity Pools peut accorder à vos utilisateurs l’accès à des services AWS.

Cognito User Pool

Les groupes d’utilisateurs Cognito permettent de découpler la gestion des utilisateurs d’une application. Ils apportent les fonctionnalités suivantes :

  • Inscription, connexion
  • Récupération du mot de passe en cas d’oubli
  • Vérification de l’email ou du numéro de téléphone
  • Stratégie de complexité du mot de passe
  • Authentification multi-facteurs (envoi d’un code par email ou SMS)
  • Connexion à travers les fournisseurs d’identité suivants : Facebook, Google, Amazon, Apple mais également à tous ceux qui utilisent les protocoles de connexion SAML et OpenID Connect

Les utilisateurs sont stockés sur AWS et accessibles via le service Cognito sur la console AWS :

Le service propose également une interface de connexion hébergée qui permet aux utilisateurs de se connecter facilement à travers un fournisseur d’identité externe. Cela se met en place facilement avec très peu de lignes de code.

Cette interface peut être légèrement personnalisée avec l’ajout d’un logo, et la modification de certaines propriétés CSS. Son utilisation n’est cependant pas obligatoire :

  • Si l’utilisateur se connecte avec son email et mot de passe, vous pouvez le faire directement depuis votre frontend en utilisant Amplify (ou le SDK Cognito).
  • Vous pouvez faire en sorte que l’interface hébergée redirige directement vers le fournisseur d’identité de votre choix avec un paramètre dans l’URL. L’utilisateur a l’impression que votre application redirige directement vers le fournisseur d’identité mais en réalité, il y a Cognito entre les deux. Amplify gère cela très facilement.

La connexion renvoie un jeton JWT qui doit être utilisé dans les requêtes.

Il est très facile de sécuriser une API s’appuyant sur API Gateway avec un User Pool Cognito. Il suffit de créer un mécanisme d’autorisation et de l’appliquer aux routes à sécuriser.

Sinon, il est possible de vérifier la validité d’un token JWT au niveau applicatif en vérifiant la signature et les claims (plus d’informations ici).

Dans de nombreuses situations, quand on parle de Cognito, on parle des User Pools Cognito. Mais il existe un autre sous-service : Identity Pool, qui a un objectif totalement différent.

Cognito Identity Pool

Cognito Identity Pool a une mission principale : transformer le jeton d’un fournisseur d’identité externe en clés d’accès temporaires IAM. AWS Identity and Access Management (IAM) est le service transversal de contrôle d’accès aux ressources AWS. Des clés d’accès permettent des actions sur des ressources AWS définies par le rôle associé aux clés.

On peut utiliser un jeton provenant :

  • D’un fournisseur d’identité public classique : Amazon, Apple, Facebook, Google et Twitter
  • D’un autre fournisseur d’identité utilisant le protocole OpenID ou SAML
  • D’un User Pool Cognito : on peut donc combiner les deux services

Ces accès permettent à l’application frontend d’accéder directement à des services AWS. Les permissions associées à ces accès temporaires sont définies par un rôle IAM. Elles peuvent être très fines car on peut y inclure l’identifiant de l’utilisateur. Si on le souhaite, on peut également donner des accès temporaires (avec des permissions différentes) à des utilisateurs non-authentifiés.

Le schéma suivant résume le fonctionnement d’un Identity Pool Cognito

On peut citer un cas d’utilisation classique :  autoriser les utilisateurs à accéder à un répertoire qui leur est propre sur un bucket S3. Cela permet au frontend de l’application de mettre des fichiers directement sur S3, de manière sécurisée, sans passer par le backend.

On peut également autoriser l’accès à une API utilisant API Gateway via une permission IAM. Dans ce cas, il faut paramétrer l’API Gateway pour utiliser la méthode d’autorisation IAM (et non pas via Cognito, ce qui correspond à un User Pool).  Par contre ce service n’est pas fait pour sécuriser une application classique.

Il faut noter que pour avoir ces accès IAM, il faut déjà avoir implémenté dans le code un mécanisme pour obtenir un jeton d’un fournisseur d’identité. Cela implique en général plus de code au niveau du frontend de l’application.

Quand utiliser un Cognito User Pool seul ?

  • Vous avez besoin de mettre en place un mécanisme d’inscription et de connexion dans votre application et vous ne souhaitez pas tout développer.
  • Vous souhaitez profiter d’un panel de fonctionnalités liées à la sécurité.
  • Vous souhaitez mettre en place de l’authentification à travers des fournisseurs d’identité externes et vous préférez le faire sans écrire de code.
  • Vous souhaitez sécuriser une API Gateway ou votre backend.
  • Vous voulez avoir accès à la liste des utilisateurs.
  • Vous avez besoin d'un fournisseur d’identité (IDP) managé.

Quand utiliser un Cognito Identity Pool seul ?

  • Vous voulez autoriser l’accès à un ou plusieurs services AWS à vos utilisateurs.
  • Vous avez déjà un jeton d’accès provenant d’un fournisseur d’identité tiers dans votre application.
  • Ou vous souhaitez développer la connexion à ce fournisseur d’identité vous même.

Quand utiliser Cognito User Pool et Cognito Identity Pool ensemble ?

On peut effectivement utiliser un Cognito User Pool en tant que fournisseur d’identité dans un Cognito Identity Pool. Cela permet par exemple à un utilisateur d’un User Pool d’obtenir des accès temporaires AWS pour récupérer du contenu sur S3 de manière sécurisée.

Il y a un autre avantage à utiliser les deux services ensemble qui est un peu moins connu : avoir un semblant de Role Based Access Control (contrôle d’accès basé sur les rôles). Dans un User Pool, on peut définir des groupes. Chaque utilisateur peut appartenir à zéro ou plusieurs groupes. On peut assigner à chaque groupe un rôle IAM. Si le User Pool est utilisé dans un Identity Pool, lors de l’échange du token JWT par des accès temporaires IAM, l'utilisateur recevra des accès avec le rôle assigné au groupe et non pas le rôle par défaut de l’Identity Pool.

On peut par exemple définir le groupe Admin qui aurait un rôle IAM leur permettant cela :

  • Appel du chemin /admin sur une API Gateway
  • Ajout et récupération d’images dans un bucket S3

Le rôle “authenticated” de l’Identity Pool permet seulement aux utilisateurs classiques les actions suivantes :

  • Appel du chemin /user sur une API Gateway
  • Récupération d’images dans un bucket S3

Il faut noter qu’utiliser un Identity Pool n’est pas le seul moyen de profiter des groupes d’un User Pool pour faire du Role Based Access Control. Le groupe étant présent dans le token JWT, il est facile d’autoriser une requête au niveau applicatif en fonction du groupe de l’utilisateur. Dans le cadre de la sécurisation d’une API Gateway, il est également possible d’utiliser une fonction Lambda en tant que “Custom Authorizer” pour vérifier le groupe de l’utilisateur.

Je tiens cependant à ajouter que faire du RBAC sur une API Gateway n’est pas tout le temps une bonne idée et qu’il est souvent plus judicieux de mettre en place un contrôle d’accès plus fin au niveau applicatif.

Conclusion

Pour résumer :

  • Amazon Cognito User Pool vous permet de découpler la gestion des utilisateurs de votre application et vous permet de vous concentrer sur la valeur que votre application apporte. A cela s’ajoute de nombreuses fonctionnalités de sécurité. La connexion renvoie un jeton JWT.
  • Amazon Cognito Identity vous permet d’échanger un jeton d’un fournisseur d’identité externe (ou un User Pool) Cognito contre un des accès temporaires IAM. Permet à vos utilisateurs d’avoir accès directement à des services AWS.

Peu importe la configuration que vous choisirez, je vous conseille d’utiliser la librairie Amplify qui vous permettra de mettre en place Cognito sur votre frontend rapidement.

Au niveau de votre backend, vous pouvez placer votre sécurité au niveau d’une API Gateway si votre application le permet. Sinon, et si vous utilisez un User Pool, vous pouvez mettre en place votre sécurité directement dans votre code applicatif en utilisant une librairie qui implémente les spécifications JWT (et ce tutoriel).