Concevoir une API REST conforme au RGPD

API loves

Vous avez sans doute entendu parler du RGPD voire implémenté ses règles dans votre SI. Il est primordial de protéger nos données personnelles à l'ère du tout-numérique. Pendant longtemps, les utilisateurs n'ont pas été maîtres des données qui leur appartiennent. L'Europe a finalement mis la main à la pâte pour définir un cadre légal autour de l'utilisation de nos informations personnelles, par les fournisseurs de services. Nous pouvons et devons l'appliquer dans nos API.

Nous allons parler des droits des personnes concernées par les données personnelles et de la gestion des consentements, relatifs à la conception, à la sécurité et à la gestion des API.

L'objectif est de fournir une base à tout développeur d'API REST mettant en œuvre une API compatible RGPD, avec à l'esprit la confidentialité dès la conception (privacy by design) et la confidentialité par défaut (privacy by default). Il s'agit d'une base et non d'une solution ultime. Vous aurez des cas plus complexes, des scénarios spécifiques qui ne pourront pas être expliqués ici.

Notez que la plupart des processus décrits dans cet article, sinon tous, peuvent être effectués à la main dans les meilleurs délais, comme indiqué dans le RGPD. Cependant, nous souhaitons fournir un moyen automatisé de faire le même travail. C'est notre job après tout, non ?

Mots-clés

Résumé

Afficher les données personnelles dans l'interface utilisateurGET /users/{id}
Éditer des informations personnellesPUT /users/{id} PATCH /users/{id}
Exporter des donnéesPOST /users/{id}/exports
Droit à l'oubliDELETE /users/{id}
Restriction d'un traitementPUT /users/{id} PATCH /users/{id}
Signaler du contenuPOST /reports GET /reports GET /reports/{id}
Collecte des consentementsPOST /users PUT /users/{id} PATCH /users/{id}
Quel âge a l'utilisateur ?POST /users

Impact sur le design d'API

Le RGPD nous oblige à concevoir nos API REST en gardant à l'esprit la confidentialité des données. Nous devons réfléchir davantage à la manière dont nous fournissons l'accès aux informations personnelles. C'est la confidentialité dès la conception (privacy by design). Nos API doivent faciliter au maximum la création, l'édition et la suppression des données, de sorte que les applications front-end puissent manipuler les données à la demande de l'utilisateur. Bien sûr, avant de mettre à jour ou de supprimer un compte d'utilisateur, une authentification et une autorisation doivent être effectuées pour s'assurer que l'utilisateur modifie bien son propre compte.

Afficher les données personnelles dans l'interface

GET /users/{id} Droit d'accès (RGPD art. 15)

La personne concernée a le droit d'obtenir du responsable du traitement la confirmation que des données à caractère personnel la concernant sont ou ne sont pas traitées et, lorsqu'elles le sont, l'accès auxdites données à caractère personnel [...]

RGPD Art. 15

Il s'agit d'afficher les données d’un utilisateur dans l’interface, c’est-à-dire sans les télécharger sur sa machine. Cela fait partie du droit d'accès et de rectification, il est donc nécessaire d'afficher les données que l'utilisateur demande.

Page de visualisation des données personnelles sans téléchargement - FacebookPage de visualisation des données personnelles sans téléchargement - Facebook

Page de visualisation des données personnelles sans téléchargement - GooglePage de visualisation des données personnelles sans téléchargement - Google

Notez que ces deux exemples semblent rassembler des données de plusieurs API. Lorsque les données utilisateurs sont réparties sur plusieurs systèmes (exemple Google ou Facebook), ce endpoint n'est pas aussi simple que d'appeler GET /users/{id}. On suppose qu'une API transverse pourrait être construite pour répondre à cet objectif. Cette API serait appelée à l'aide du endpoint précédent. Elle appellerait ensuite d'autres API pour collecter toutes les données disponibles sur un utilisateur.

Éditer des informations personnelles

PUT /users/{id} PATCH /users/{id} Droit d'accès et de rectification (RGPD art. 15 et 16)

La personne concernée a le droit d'obtenir du responsable du traitement, dans les meilleurs délais, la rectification des données à caractère personnel la concernant qui sont inexactes. Compte tenu des finalités du traitement, la personne concernée a le droit d'obtenir que les données à caractère personnel incomplètes soient complétées, y compris en fournissant une déclaration complémentaire.

RGPD art. 16

L'appel API ressemblerait à ceci :

PUT /users/{id}
{
  "id": "ab431c431-def112-fgdab12450",
  "name": "John Doe",
  "email": "john.doe@example.com",
  [...]
}
⇒ 200 OK avec la nouvelle représentation de l’utilisateur

Le verbe PATCH peut également être utilisé pour n’envoyer que le champ modifié. Cela pourrait ressembler à ce qui suit :

PATCH /users/{id}
{
  "email": "john.definitely.not.doe@example.com"
}
⇒ 200 OK avec la nouvelle représentation de l'utilisateur

Un exemple chez Google :

Page de visualisation des données personnelles - GooglePage de visualisation des données personnelles - Google

Exporter des données

POST /users/{id}/exports Droit à la portabilité des données (RGPD art. 20)

Les personnes concernées ont le droit de recevoir les données à caractère personnel les concernant qu'elles ont fournies à un responsable du traitement, dans un format structuré, couramment utilisé et lisible par machine, et ont le droit de transmettre ces données à un autre responsable du traitement sans que le responsable du traitement auquel les données à caractère personnel ont été communiquées y fasse obstacle [...]

RGPD art. 20

Dans un monde merveilleux, ce cas d'utilisation consiste simplement à chercher un utilisateur par son identifiant et à renvoyer les données au format demandé. Si votre modèle de données est simple, cela peut être le cas. Si ce n'est pas le cas, par exemple si la collecte de données auprès de plusieurs systèmes distants prend beaucoup de temps, vous devriez plutôt répondre 202 Accepted et envoyer les données de l'utilisateur dès que possible (par email ou tout autre moyen). Le RGPD mentionne des "délais raisonnables" mais dans la plupart des cas, cela se comptera en minutes. Récapitulons dans un tableau pour que cela soit plus clair.

Export immédiatExport long
POST /users/{id}/exports
Répondre 201 Created avec un header Content-TypeRépondre 202 Accepted
Renvoie les informations au format demandé (JSON, CSV ou encore YAML)Rassemble les données et crée un export ultérieurement
Les informations personnelles sont envoyées tout de suiteLes informations personnelles sont envoyées ultérieurement dans un email
Simple (création d'entité)Un peu plus de travail (création d'entité + batch + email)
Affichage d’un fichier à télécharger dans l'application frontTéléchargement depuis l'e-mail en pièce jointe

Le processus n'a pas d'importance. Il doit être facile pour un utilisateur d'accéder à ses données. Voici de bons exemples d’export de données sur Facebook et Google.

Page d'export de données - FacebookPage d'export de données - Facebook

Page d’export de données - GooglePage d’export de données - Google

Facebook et Google vous permettent de télécharger toutes vos données en quelques clics. Vous pouvez même choisir la plage de temps, le format ou la qualité de média que vous désirez !

Ces paramètres peuvent être passés dans le corps (body) de la requête. Il dépend grandement de la nature des données à exporter. Cependant, certains paramètres peuvent être commun comme la plage temporelle et le format d’export.

Droit à l'oubli

DELETE /users/{id} Droit à l'effacement et obligation de notification (RGPD art. 17 et 19)

“Oubliez-moi” - vous devriez avoir une méthode qui prend un userId et supprime toutes les données personnelles sur cet utilisateur (si elles ont été collectées sur la base du consentement sur les intérêts légitimes du responsable du traitement (voir ci-dessous) et non en raison de l'exécution forcée d'un contrat ou d'une obligation légale). [...]

Nous devons exposer un endpoint pour la suppression du compte utilisateur et en particulier de ses informations personnelles contenues dans la base de données. En outre, la loi nous oblige à vraiment effacer le compte utilisateur. Il ne doit pas être conservé avec un champ disant par exemple "deletedAt": "2018-01-01T00:00:00Z".

DELETE /users/{id}
⇒ 204 No Content

Avertir des tiers en vue de leur effacement - la suppression d'éléments de votre système est une chose, mais vous devez également informer tous les tiers auxquels vous avez transmis ces données. Par conséquent, si vous avez envoyé des données personnelles à, par exemple, Salesforce, Hubspot, Twitter ou tout autre fournisseur de services cloud, vous devez appeler leur API qui permet la suppression de données personnelles. [...]

Nous devons également appeler les API d'autres fournisseurs pour supprimer les informations personnelles. Si un tiers donné ne fournit pas de endpoint pour la suppression des données utilisateur, il doit être contacté manuellement. Ceci est applicable à toute donnée personnelle de la personne concernée. Il s’agit de l’obligation de notification tel que décrit dans l’article 19 du RGPD.

Par exemple, si votre API a stocké des fichiers appartenant à l’utilisateur, en son nom, sur Google Drive, vous devez appeler l’API Drive pour supprimer ces données, si c’est pertinent.

Attention, il peut exister des restrictions légales à l’effacement, au sens de l’article 23, qui incluent mais ne se limitent pas à la sécurité nationale, à l'intérêt public, à l'application de la loi (l’utilisateur est impliqué dans un procès, ses données ne doivent pas être effacées pour l'instant), etc.

Restriction du traitement

PUT /users/{id} PATCH /users/{id} Droit de à la limitation du traitement (RGPD art. 18)

La personne concernée a le droit d'obtenir du responsable du traitement la limitation du traitement [...]

RGPD art. 18

Le traitement des données doit pouvoir être limité à la demande de la personne concernée dans les termes définis par la loi. Cela signifie que le responsable du traitement des données peut conserver les informations personnelles concernées, mais ne peut plus les traiter. Cette solution peut être mise en œuvre par élément (par exemple une photo) ou par utilisateur. Cela rendrait un compte d'utilisateur inactif.

Cette restriction peut être apposée comme suit :

PUT /users/{id}
{
  "id": "ab431c431-def112-fgdab12450",
  "name": "John Doe",
  "email": "john.doe@example.com "
  "restricted": true,
  [...]
}
⇒ 204 No content

Suite à cette restriction, la personne concernée (c'est-à-dire l'utilisateur) doit donner son consentement pour que ses données à caractère personnel soient à nouveau traitées.

Attention, les mêmes restrictions légales que le droit à l'oubli s'appliquent.

L'exemple de Facebook

Prenons un autre exemple. Imaginez que vous apparaissiez sur une photo postée par quelqu'un d'autre sur votre réseau social préféré. Vous ne voulez pas que cette photo soit publique, alors vous demandez à Facebook de la retirer car elle a été postée sans votre consentement. C'est le droit à l’effacement. De plus, la photo sera dépubliée pendant le traitement de la demande par l'équipe support. C'est ce qu'on appelle le droit à la limitation du traitement.

Lors de l'obtention d'un élément par ID après l'activation de la restriction, l'API doit répondre 404 Not found si l'appelant n'est pas le propriétaire des données.

Signalement

POST /reports GET /reports GET /reports/{id} Droit à la limitation du traitement et à l’effacement (RGPD art. 17, art. 18, art. 19)

Il existe des cas dans lesquels une personne est concernée par des données personnelles qu’elle n’a pas publiées. Il est facile d'automatiser la suppression lorsque les données sont publiées par la personne concernée. Par exemple, on peut supprimer sa propre photo sur Facebook. Cependant, on ne peut pas supprimer la photo de quelqu'un d'autre sur laquelle on apparaît.

Si vous tombez sur le même cas d'utilisation dans votre application, vous devrez peut-être implémenter une fonctionnalité de signalement. C'est d’ailleurs la solution de Facebook. Vous demandez le retrait d'une photo sur laquelle vous apparaissez sans y avoir consenti, en exerçant votre droit à l’effacement. Cela pourrait être implémenté comme suit :

POST /reports
{
  "itemId": "17bd6455-aca3-4289-8684-3d956271f7c7",
  "type": "photo"
}
⇒ 202 Accepted
{
  "id": "56dbdf9e-861e-4baa -8d3a-d2dd16c5694a",
  "itemId": "17bd6455-aca3-4289-8684-3d956271f7c7",
  "type": "photo",
  "status": "pending"
}

Cela créerait un rapport sur un élément avec un type égal à photo. N'oubliez pas de conserver l'ID utilisateur dans le rapport stocké en base de données. Vous pouvez l'obtenir à partir du champ "sub" du jeton d'accès (access token) si votre jeton d'accès est un JWT standard.

Cette solution est intéressante car les signalements peuvent être développés sans impact sur les autres ressources. Le endpoint renverrait 202 Accepted, pour indiquer qu'un processus (en l'occurence humain) est effectué en arrière-plan.

Lorsque la personne concernée vérifierait ses rapports traités dans votre application cliente, elle appellerait par exemple :

GET /reports?status=done
⇒ 200 OK (ou 206 Partial Content s'il y a pagination)
[
  {
    "id": "56dbdf9e-861e-4baa-8d3a-d2dd16c5694a",
    "itemId": "17bd6455-aca3-4289-8684-3d956271f7c7",
    "type": "photo",
    "status": "done"
  },
  [...]
]

De plus, en vertu de l’article 19 du RGPD, le responsable du traitement est tenu de notifier les sous-traitants — ayant accès à la donnée concernée — de la limitation du traitement. Les sous-traitants devront donc à leur tour cesser de traiter la photo en question.

Collecte des consentements

POST /users PUT /users/{id} PATCH /users/{id}

Les consentements des utilisateurs doivent être recueillis dans le respect de la loi. Les cases à cocher, les switchs — peu importe comment vous appelez cela — doivent indiquer exactement ce que vous collectez et pourquoi. Ces choix doivent être envoyés à l'API lors de la création ou de la mise à jour d'un utilisateur. Notez que ces champs de consentement doivent être définis à faux par défaut. Ainsi, lorsqu'un utilisateur crée son compte, il doit explicitement accepter vos différentes conditions.

Il est important de suivre les modifications apportées aux consentements. Cela n’a pas d’impact sur la conception des API, car il n’y a pas d’autre champ à envoyer. Si une valeur de consentement change, un événement doit être ajouté à l'historique, dans la base de données.

PUT /users/{id}
{
  "id": "ab431c431-def112-fgdab12450",
  "name": "John Doe",
  "email": "john.doe@example.com"
  "restricted": false,
  "consents": {
    "shareWithPartners": true,
    "contactable": true,
    [...]
  },
  [...]
}
⇒ 200 OK avec la nouvelle représentation de l'utilisateur

Ici, l'utilisateur a mis à jour son consentement. C'est un cas où le modèle utilisateur comporte peu de champs. Il n'est pas nécessaire de séparer les informations essentielles de l'utilisateur et les paramètres et autorisations spécifiques. Serait-il préférable de les séparer dès le début ? Nous pourrions. Cela permettrait aux paramètres de se développer indépendamment des informations de l'utilisateur. Cela pourrait être utile surtout si la loi évolue beaucoup.

On peut effectuer la même opération en utilisant le verbe PATCH :

PATCH /users/{id}
{
  "consents": {
    "shareWithPartners": true,
    "contactable": true
  }
}

NB: dans le RGPD, il est permis de ne pas demander le consentement de l'utilisateur en cas d'intérêt légitime. Imaginez que dirigiez une société de livraison. Vous avez besoin de l'adresse de livraison pour acheminer les colis. Cela s'appelle un intérêt légitime. Vous devez indiquer à l'utilisateur, dans le contrat, que vous avez besoin de son adresse de livraison pour livrer les marchandises. Si l'utilisateur accepte ce contrat et que l’intérêt est justifié, vous pouvez utiliser l’adresse de livraison à cette fin.

Il existe six moyens de légitimer un traitement qui comprennent :

  • Un contrat
  • Un consentement
  • L'intérêt vital d'un individu
  • L'intérêt public
  • Une application de loi
  • L'intérêt légitime du processeur de données

Quel âge a l'utilisateur?

POST /users

Vérification de l'âge - vous devez demander l'âge de l'utilisateur. Si l'utilisateur est un enfant (moins de 16 ans), vous devez demander la permission du parent. Il n’existe aucun moyen clair de le faire, mais je suggère d’introduire un flux dans lequel l’enfant devrait spécifier l'email d’un parent, qui peut ensuite confirmer. Évidemment, les enfants tricheront simplement avec leur date de naissance ou fourniront un faux email de leurs parents, mais vous aurez probablement fait votre travail conformément au règlement.

Ce point est difficile à suivre. Vous devez vous assurer que au moins un tuteur légal a donné son accord pour que l'enfant utilise votre application. Qu'est-ce qu'un enfant ? Une personne âgée de 13 à 16 ans, telle que mentionnée dans le RGPD. Le règlement dit que vous devez faire de votre mieux pour vous assurer que le tuteur de l'enfant donne son consentement. Ça ne peut pas être simplement une case à cocher car on vise le best effort. Le mieux que nous puissions faire est de lier le compte du tuteur au compte de l'enfant ou envoyer un email au tuteur afin qu'il confirme son consentement en cliquant sur un lien à usage unique.

Dans le cas où un enfant entrerait sa date de naissance, l’API devrait demander l’adresse email du parent.

POST /users
{
  "name": "John Doe",
  "email": "john.doe@example.com"
  "birthdate": "2005-01-01T12:00:00Z",
  "parentEmail": "mother.doe@example.com",
  [...]
}
⇒ 201 Created avec un header Location pointant vers le nouvel utilisateur

Ces champs ne peuvent évidemment pas être traités avec confiance. Un enfant peut tricher sur sa date de naissance ou donner un faux email. Cet effort de développement peut surpasser les avantages.

Approbation d'un parent ou tuteurApprobation d'un parent ou tuteur

Impact sur la sécurité

Ce sont des bonnes pratiques que vous devriez déjà suivre, mais un rappel ne fait pas de mal. Ces bonnes pratiques sont bien entendu non exhaustives.

Communications réseau

TL; DR: utilisez HTTPS.

Vous ne devez accepter que les communications sécurisées depuis et vers votre API. Cela implique l'utilisation de TLS partout où cela est nécessaire, y compris les demandes et les réponses des applications clientes, ou la communication avec des bases de données et des services externes. Tout cela doit être sécurisé.

Anonymisation des données et pseudonymisation

La protection de la vie privée dès la conception signifie que vous devez gérer la sécurité des données que vous traitez. Si votre base de données est compromise, personne ne doit pouvoir lire les données personnelles des utilisateurs. L'anonymisation est une méthode pour supprimer complètement les informations permettant d'identifier un utilisateur. Cependant, vous ne pourrez plus utiliser ces données. C'est là qu'intervient la pseudonymisation.

La pseudonymisation est un moyen d'empêcher la manipulation de données à caractère personnel sans informations supplémentaires et nécessaires. Ce concept peut être implémenté en chiffrant la base de données. Cela éviterait la fuite d'informations au cas où la base de données serait compromise. Impossible de déchiffrer la base de données sans une clé.

Les données de test doivent être soit anonymisées, soit pseudonymisées, soit intentionnellement factices.

Scopes OAuth2 et OpenID Connect

Dans les protocoles OAuth2 et OpenID Connect, dans certains cas, l'utilisateur final doit donner son consentement pour que l'application traite ses données. Dans OpenID Connect, il consiste la plupart du temps à lire l'adresse email et le profil de l'utilisateur. Il n'y a pas grand chose à changer dans ce processus, car les utilisateurs se voient présenter des écrans qui demandent explicitement leur consentement. Une chose que nous pourrions faire est d’améliorer la description du scope afin qu'il soit aussi claire et concis que possible.

Journaux de logs

Vous devez enregistrer les accès aux données sensibles tels que l'accès, l'édition et la suppression de données personnelles. Il existe des tonnes d'excellents articles sur le sujet, comme celui-ci par exemple.

Impact sur le portail développeur

Concernant les utilisateurs finaux

Dans certains cas, vos API sont ouvertes aux développeurs externes. Le RGPD a un impact direct sur votre portail développeur et les applications tierces que vous gérez. En tant que fournisseur d'API, vous êtes le processeur de données. Les applications tierces appelant votre API sont des contrôleurs de données, car elles collectent et traitent les données et les transmettent à votre API.

En tant que responsable du traitement de données, vous devez fournir aux contrôleurs de données les moyens de gérer les données personnelles des utilisateurs. Par conséquent, vous devez proposer une documentation utile sur la manière d'intégrer vos API et informer les développeurs pour qu'ils se conforment au RGPD. Les développeurs d'applications pourront ainsi mettre en œuvre des moyens pour récupérer, éditer ou supprimer des données personnelles, grâce à vos API.

Voici un exemple intéressant de ces responsabilités partagées pour le cas d'utilisation Auth0.

Concernant les développeurs

En tant que gérant du portail développeur, vous êtes responsable de la manipulation des données à caractère personnel des développeurs. Vous devez indiquer clairement quelles données vous collectez, comment vous les traitez, si vous souhaitez les partager avec des processeurs tiers, etc. Vous pouvez l'insérer dans une déclaration de confidentialité, sur la page d'inscription ou sur une page à part.

Les développeurs doivent donner leur consentement afin que vous traitiez leurs données. Dans de nombreux cas, vous aurez besoin de leur email pour les enregistrer ou extraire leurs informations auprès d'un fournisseur d'identité tel que GitHub ou Google à l'aide du protocole OpenID Connect. Le RGPD s'applique pour vous, car votre population est ici un ensemble des développeurs. Vous fournissez l'application i.e. le portail développeur. Si votre portail est en SaaS, le RGPD s'applique aussi pour votre fournisseur de service.

Conclusion

Le RGPD ne doit pas être vu comme une contrainte, mais plutôt comme une opportunité de livrer des applications plus robustes, plus modulaires et flexibles en production. La confidentialité des données personnelles a trop longtemps été délaissée par de nombreux acteurs du monde numérique. En tant qu'utilisateurs et développeurs, nous devons reprendre la main sur nos données. Et cela commence dans nos API. Dès la conception, et par défaut.

Merci !

Sources

https://RGPD-info.eu https://www.cnil.fr/fr/reglement-europeen-protection-donnees https://developer.ibm.com/articles/s-RGPD1/ https://techblog.bozho.net/RGPD-practical-guide-developers/ https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX%3A32016R0679 https://medium.com/ft-product-technology/a-developers-guide-to-RGPD-that-won-t- make-you-sweat-4f1f7f1d9c8b https://www.smashingmagazine.com/2018/02/RGPD-for-web-developers/ https://www.smashingmagazine.com/2017/07/privacy-by-design-framework/ https://fr.newsroom.fb.com/news/2018/04/facebook-se-conforme-aux-nouvelles-lois-sur-la-protection-de-la-vie-privee-et-offre-offre-de -nouvelles-protections-a-tous-partout-dans-le-monde/ Pages de visualisation et d'export de données de Google et Google. Page de consentement parental de Facebook.