Pour les équipes sécurité et les relecteurs d’applications
La sécurité chez Peel
En bref : le contenu des tableaux est chiffré dans le navigateur avec une clé qui vit dans le fragment du lien, si bien que nos serveurs stockent et relaient du texte chiffré qu’ils ne peuvent pas lire. Voici exactement comment, et où sont les limites.
Résumé
- Le texte des cartes, les noms, les titres de tableaux, les votes et les stickers sont chiffrés en AES-256-GCM avec une clé de tableau générée dans le navigateur. La clé voyage dans le fragment de l’URL (
#k=) et n’est jamais envoyée à un serveur. - Les actions du facilitateur, l’en-tête du tableau et les snapshots sont signés avec la clé Ed25519 du facilitateur. L’identifiant du tableau est dérivé de cette clé, ce qui permet aux clients de détecter une substitution de clé.
- Les cartes cachées sont scellées pour le facilitateur (sealed box X25519) jusqu’à la révélation, et liées par des engagements salés pour que le texte révélé ne puisse pas être échangé.
- Anonyme par défaut : les opérations ne portent aucun identifiant d’auteur ; les votes et réactions utilisent un identifiant aléatoire propre à chaque tableau.
- Les participants ne s’authentifient jamais. Pas de SDK d’analytics, pas de pub, pas de scripts tiers, à part Paddle.js sur la page de paiement.
- Uniquement Cloudflare. Les tableaux non revendiqués sont supprimés 60 jours après la dernière visite.
Comment circulent les données
Le fragment d’une URL (tout ce qui suit le #) est géré par le navigateur et ne fait pas partie de la requête HTTP. C’est là que Peel place la clé du tableau.
Modèle de menace
Nous concevons Peel pour qu’un serveur entièrement compromis ou curieux, nous compris, apprenne le moins possible de ce que dit une équipe.
Ce que nous protégeons
- Le texte des cartes, le choix des GIF et, en mode nominatif, le nom de l’auteur.
- Les noms et avatars des participants, le nom du tableau et les titres de modèles personnalisés.
- Qui a voté ou réagi sur quoi, et qui a écrit quelle carte.
- L’intégrité de la rétro : étapes, révélations et décisions du facilitateur ne peuvent pas être falsifiées.
Les adversaires envisagés
- Nos propres serveurs, un initié malveillant, ou quelqu’un qui pénètre notre stockage : ils obtiennent du texte chiffré et des métadonnées.
- Un attaquant sur le réseau : TLS partout ; la clé ne transite jamais sur le réseau.
- Un serveur qui substitue les clés : l’identifiant du tableau est dérivé de la clé publique du facilitateur, et les clients vérifient l’en-tête signé.
- Un participant qui veut jeter un œil ou falsifier : les cartes cachées sont scellées pour le facilitateur ; les opérations du facilitateur exigent sa signature ; modifier une carte exige la clé de la carte.
- Un facilitateur qui republie pour un auteur hors ligne : les engagements l’empêchent de modifier le texte.
Hors périmètre, en toute franchise
- Quiconque possède le lien participant peut lire le tableau. Le lien est le contrôle d’accès. Il se partage avec le même soin que le tableau lui-même.
- Un appareil compromis, une extension de navigateur malveillante, ou quelqu’un qui regarde par-dessus l’épaule.
- L’analyse de trafic : le serveur voit les horaires, les tailles et les compteurs (voir la cartographie des données).
- Le déni de service par le serveur : il peut supprimer ou retarder des messages, mais pas les lire ni les falsifier.
Cryptographie
Toutes les primitives viennent de l’API WebCrypto du navigateur. Pas de cryptographie maison, pas de bibliothèques crypto tierces.
| Clé | Algorithme | Utilisation |
|---|---|---|
| K_board | AES-256-GCM, IV aléatoire de 96 bits | Chiffre chaque opération, chaque snapshot et chaque mise à jour de présence. Les données additionnelles lient l’identifiant du tableau, le type et l’identifiant de l’opération, si bien qu’un texte chiffré ne peut pas être rejoué dans un autre tableau ou un autre emplacement. Vit uniquement dans le fragment du lien #k=. |
| K_owner | Ed25519 | L’autorité du facilitateur. Signe les opérations du facilitateur (étape, minuteur, projecteur, modèle, réglages, ouverture des votes, masquage d’une carte), l’en-tête du tableau et les snapshots. Un compteur strictement croissant bloque le rejeu. Uniquement dans le lien facilitateur (&o=). |
| Identifiant du tableau | SHA-256, 80 premiers bits, base32 | Dérivé de la clé publique du facilitateur : l’identifiant prouve à lui seul quelle clé possède le tableau. Les clients rejettent un en-tête dont la clé ne correspond pas à l’empreinte de l’identifiant. |
| K_fac | Sealed box X25519 : X25519 éphémère + HKDF-SHA256 + AES-256-GCM | Les cartes cachées sont scellées avec la clé publique du facilitateur pendant l’écriture. Seul le lien facilitateur (&f=) peut les ouvrir. |
| Clés de carte | Ed25519, une clé par carte | Détenue uniquement par l’auteur. Les modifications et la révélation sont signées avec : l’authenticité sans l’identité. |
| Engagements | HMAC-SHA256 avec un sel aléatoire de 128 bits | Une carte cachée publie un engagement sur son contenu. À la révélation, le contenu et le sel sont publiés et chaque client les vérifie : personne ne peut échanger le texte. |
| Présence | AES-256-GCM avec K_board | Les noms, avatars et indicateurs de saisie sont chiffrés comme tout le reste. |
| Trousseau de clés | HKDF-SHA256 à partir du PRF de la clé d’accès ou du code de récupération, AES-256-GCM | Les facilitateurs connectés peuvent synchroniser leurs clés de tableau entre appareils. Le trousseau est chiffré sur l’appareil ; le serveur ne stocke que du texte chiffré et des clés enveloppées. |
Les messages signés sont séparés par domaine (par exemple peel/sig/v1, peel/header/v1, peel/snap/v1) pour qu’une signature produite pour un usage ne puisse pas être réutilisée pour un autre.
Anonymat
- Les opérations ne portent aucun identifiant d’auteur. Le serveur ne peut pas relier une carte à une personne, et par défaut le facilitateur non plus.
- Les votes et réactions sont associés à un identifiant aléatoire propre au tableau, qui n’est lié à aucun nom.
- Les indicateurs de saisie montrent que quelqu’un écrit, jamais ce qu’il écrit.
- Le mode nominatif est un réglage explicite du tableau ; le nom de l’auteur voyage alors à l’intérieur de la carte chiffrée.
- Les participants ne se connectent jamais : il n’y a donc aucun compte à recouper.
Cartographie des données
Tout ce que nous conservons, où cela se trouve, qui peut le lire et combien de temps cela reste.
| Données | Où | Lisible par | Conservation |
|---|---|---|---|
| Cartes, votes, réactions, stickers, actions, nom du tableau, titres de modèles personnalisés | Stockage Durable Object, sous forme chiffrée | Les personnes qui ont le lien du tableau | Jusqu’à la suppression du tableau |
| Enveloppe d’opération : type, séquence et heure côté serveur, taille, compteur du facilitateur | Stockage Durable Object | Peel | Jusqu’à la suppression du tableau |
| Noms et avatars des participants, saisie en cours | Relayés sous forme chiffrée ; gardés en mémoire pendant la connexion | Les personnes qui ont le lien du tableau | Pendant la connexion |
| Statut du tableau : étape, nombre de participants et de cartes, identifiant du modèle du catalogue, indicateur de verrouillage, dates de création et d’expiration | Durable Object, D1 ; messages Slack/Teams si installé | Peel ; votre canal Slack/Teams | Durée de vie du tableau |
| Compte facilitateur : identifiant du fournisseur, nom, e-mail s’il est partagé, fournisseurs liés, date de création, session | D1 | Peel | Jusqu’à la suppression du compte |
| Trousseau de clés et clés enveloppées | D1, sous forme chiffrée | Uniquement le titulaire du compte (clé d’accès ou code de récupération) | Jusqu’à la suppression du compte |
| Offre, statut de l’abonnement, identifiants client et abonnement Paddle | D1 ; Paddle | Peel, Paddle | Selon les obligations fiscales |
| Identifiants d’espace de travail, de canal et de message Slack/Teams ; jeton du bot (chiffré en AES-GCM) | D1 | Peel | Jusqu’à la désinstallation |
| Adresse IP | Edge Cloudflare, de façon transitoire (acheminement, limitation de débit) | Cloudflare, le limiteur de débit de Peel | Non stockée dans nos bases de données |
| Compteurs quotidiens (tableaux créés, étapes atteintes) | D1 | Peel | Agrégés uniquement, sans identifiant |
Ce que notre serveur peut faire, et ce qu’il ne peut pas
Il peut
- Voir les types d’opérations, les tailles, les horaires, l’étape, le nombre de participants et de cartes, l’identifiant du modèle du catalogue et l’indicateur de verrouillage.
- Supprimer, retarder ou refuser de livrer des opérations (déni de service).
- Voir les adresses IP en bordure de réseau.
- Compter les tableaux et les étapes atteintes, de façon agrégée.
- Supprimer un tableau (expiration, signalements d’abus).
Il ne peut pas
- Lire le texte des cartes, les noms, les titres de tableaux, les titres de modèles personnalisés, les votes ou les stickers.
- Lire les cartes cachées avant la révélation (ni même après).
- Falsifier les actions du facilitateur : elles exigent sa signature.
- Substituer ses propres clés : l’identifiant du tableau le trahirait.
- Modifier le texte révélé d’une carte : les engagements et les signatures de carte le trahiraient.
- Savoir qui a écrit quelle carte.
Comme pour toute application web, il faut faire confiance au code que nous servons. Nous gardons cette surface réduite : une Content Security Policy stricte, script-src limité à notre propre origine, aucun script tiers, et le protocole est ouvert à l’examen sur demande.
Slack et Microsoft Teams
- Les messages transportent le lien du tableau et des métadonnées (titre, étape, compteurs). Le texte des cartes n’est envoyé que lorsque le facilitateur publie un résumé et le confirme.
- La carte « Rejoindre » contient le lien participant, qui inclut la clé. Quiconque peut lire ce canal peut rejoindre, comme si le lien y avait été collé.
- Les aperçus de liens n’affichent que l’étape et les compteurs, jamais le contenu.
- Scopes Slack :
commands,chat:write,links:read,links:write;users:readuniquement quand une équipe active les mentions. - Les jetons de bot sont chiffrés au repos (AES-GCM, clé conservée comme secret du Worker). Les signatures des requêtes Slack et les jetons Bot Framework sont vérifiés à chaque requête.
- Désinstaller l’app arrête toute publication et supprime ses jetons.
Web et infrastructure
- Uniquement Cloudflare : Pages, Workers, Durable Objects, D1, R2 et KV sur le compte de 1801 Labs. Aucun autre serveur.
- TLS partout, HSTS et une Content Security Policy stricte.
- Pas de SDK d’analytics, pas de pub, pas de scripts tiers. Seule exception : Paddle.js, chargé uniquement sur la page de paiement.
- Un seul cookie, uniquement pour les facilitateurs connectés :
peel_session, httpOnly, Secure, SameSite=Lax. - La recherche de GIF et les médias passent par notre API, si bien que les adresses IP des participants n’atteignent jamais GIPHY.
- Polices et ressources auto-hébergées. Pas de polices sur CDN, pas de pixels de suivi.
- Limitation de débit par IP et par tableau ; signalements d’abus et verrouillage par le facilitateur.
Comptes et conservation
- Les participants ne s’authentifient jamais. Les facilitateurs se connectent avec Google (ou Entra ID via Teams), uniquement pour garder leurs tableaux ou utiliser les fonctionnalités payantes.
- Un compte stocke un identifiant, le nom et l’e-mail fournis par le fournisseur, et un trousseau de clés chiffré, déverrouillé par une clé d’accès (WebAuthn PRF) ou un code de récupération. Se connecter donne la propriété, pas l’accès au contenu.
- Revendiquer un tableau prouve la propriété par une signature du facilitateur. Les clés de tableau ne sont jamais envoyées.
- Les tableaux sans compte sont supprimés 60 jours après la dernière visite ; chaque visite remet le compteur à zéro. Des alarmes Durable Object suppriment le stockage.
- Supprimer son compte supprime les sessions, le trousseau de clés et la bibliothèque, et redonne aux tableaux leur expiration à 60 jours.
Divulgation responsable
Vous avez trouvé quelque chose ? Prévenez-nous d’abord et nous travaillerons avec vous. Nous accusons réception des signalements sous trois jours ouvrés.
- Merci de nous laisser un délai raisonnable (nous visons 90 jours) pour corriger avant toute divulgation.
- Testez avec vos propres tableaux et comptes. N’accédez pas aux données d’autrui et ne dégradez pas le service.
- Nous n’engagerons pas de poursuites contre une recherche menée de bonne foi dans le respect de ces règles.
- Contact lisible par machine :
/.well-known/security.txt.
Les clients de l’offre Entreprise reçoivent un dossier d’évaluation de sécurité (réponses aux questionnaires, sous-traitants, flux de données). DPA · Confidentialité