Comment une page statique peut collecter des données sans les laisser fuir
Votre site Bailey n'a aucun serveur ni aucune clé secrète enfouie dedans, et pourtant il peut mémoriser et collecter, en toute sécurité. Voici le modèle qui rend ça possible, en clair.
Un site Bailey, ce ne sont que des fichiers statiques : du HTML, du CSS, un peu de JavaScript. Aucun serveur à gérer, aucune base de données à configurer, et surtout aucune clé d’API secrète cachée dans la page. Et pourtant cette page peut mémoriser des choses et collecter des soumissions de formulaire, en toute sécurité, sans que les données d’un créateur ne débordent jamais sur celles d’un autre.
Les gens qui ont déjà construit ce genre de chose haussent en général un sourcil devant cette affirmation. S’il n’y a pas de secret dans la page, qu’est-ce qui empêche n’importe qui d’écrire dans vos données ? Si tout est statique, où part la soumission du formulaire ? Questions légitimes. Voici la réponse.
Ce que nous refusons de faire
La manière naïve de laisser une page statique parler à un backend, c’est d’enfouir une clé d’API dans le JavaScript. Surtout pas. N’importe qui peut ouvrir les outils de développement, lire la clé, et voilà : il possède votre plan de données. « Le front statique détient un secret » est le péché originel d’une bonne partie de l’outillage no-code.
La première règle de Bailey : un front statique ne détient aucun secret. L’accès n’est pas borné par le secret d’une clé, puisqu’il n’y a aucune clé à garder secrète. Il est borné par autre chose.
Des jetons servis à la volée, pas des clés enfouies
Quand Bailey sert votre page, il forge un jeton à durée de vie courte, restreint à cette page, ce visiteur, maintenant. Le jeton porte un jeu serré de contraintes :
- une durée de vie courte, pour qu’un jeton copié ne vaille plus rien en quelques minutes ;
- un nonce à usage unique, pour qu’il ne puisse pas être rejoué ;
- un lien à l’Origin/CORS, pour qu’il ne fonctionne qu’appelé depuis votre vrai site.
La page utilise ce jeton pour écrire dans le store. On ne lui a jamais remis les clés du royaume, seulement un laissez-passer étroit, expirant, à usage unique. Associez ça à une visibilité en insertion seule (un formulaire peut ajouter une soumission mais ne peut pas relire ce que les autres ont soumis) et à une limitation de débit, et une copie hostile de votre page ne peut quasiment rien faire d’utile.
L’isolation est imposée deux fois
L’invariant non négociable, c’est A ≠ B : le projet A ne lit ni ne sert jamais les fichiers ou les données du projet B. Nous ne faisons pas confiance à une seule couche pour le garantir, alors nous l’imposons à deux endroits qui doivent tous les deux être d’accord :
- Au niveau du noyau. Les fichiers sont servis à travers un bac à sable au
niveau du système (
os.Root) qui ne peut physiquement pas sortir du répertoire propre à un projet. Les astuces de chemin ne vous en font pas sortir. - Au niveau de la politique. Chaque lecture et chaque écriture dans le store
est vérifiée contre le propriétaire estampillé sur la requête : un appel
Authorizeadossé à un identifiant propre à chaque projet. Pas de correspondance, pas d’accès.
Bretelles et ceinture. Chacune des deux couches suffirait à stopper une fuite ; les deux doivent tenir, et les deux sont testées.
Qui vous êtes vient du jeton, jamais du contenu de la requête
En voici une subtile, qui compte beaucoup. Quand une requête dit « enregistre ça pour le projet X », nous ne croyons pas la partie « projet X » si elle se trouve dans le corps de la requête. L’identité du propriétaire est lue depuis le jeton validé qu’a émis le serveur, jamais depuis des données fournies par le client. Autrement, l’usurpation serait une attaque en une ligne : il suffirait de prétendre être quelqu’un d’autre. L’identité est estampillée côté serveur, point final.
La chaîne d’or du RGPD
Dernière pièce. Une page qui collecte des données personnelles doit déclarer pourquoi : sa finalité. Si un formulaire veut collecter des e-mails et ne dit pas à quelle fin, Bailey refuse de le publier. Pas un avertissement, un refus. Les finalités sont déclarées d’emblée, réconciliées à chaque publication, et les compartiments de données ne sont jamais supprimés en silence sous vos pieds.
Le bénéfice pour vous : quand un visiteur demande « qu’avez-vous sur moi, et pouvez-vous l’effacer ? », la réponse tient en un clic, parce que le système a été bâti pour répondre à cette question dès le premier jour.
Rien de tout cela ne se configure. Vous demandez à votre assistant de publier une page, et tout ce qui précède est simplement actif. C’est toute l’idée : une gouvernance à laquelle vous n’avez pas à penser, parce que c’est le plancher, pas une option.