Chaque plate-forme performante atteint un point où elle doit permettre aux autres d'écrire le code qui s'y exécute. Plugins utilisateur, fonctions client d'entreprise personnalisées, extensions partenaires, règles métier envoyées via API. Le problème est toujours le même : comment exécuter du code que vous n'avez pas écrit, sur une infrastructure que vous contrôlez, sans transformer cette ouverture en vulnérabilité ? Les réponses traditionnelles sont coûteuses, lentes ou fragiles. WebAssembly offre une réponse différente – et comprendre pourquoi nécessite de comprendre ce qui rend le problème difficile.
Pourquoi les solutions traditionnelles ne sont pas évolutives
La première tentative de nombreuses équipes est eval() ou équivalent : exécuter la chaîne de code directement au moment de l'exécution. C’est rapide à mettre en œuvre et catastrophique à maintenir. Le code du plugin a accès à tout ce dont dispose le processus hôte : mémoire, réseau, système de fichiers. Un plugin malveillant ou simplement défectueux peut faire échouer l’ensemble du processus ou exfiltrer les données d’autres locataires.
La deuxième tentative est un microservice de plugin : chaque extension s'exécute dans un conteneur isolé. Cela fonctionne du point de vue de la sécurité, mais le coût opérationnel augmente linéairement avec le nombre de plugins. Il est impossible de conserver un conteneur par client sur des plates-formes comportant des centaines d'extensions. La latence de chaque appel entre conteneurs pénalise également les opérations qui devraient être inférieures à la milliseconde.
Les processus enfants avec des espaces de noms Linux sont une autre option : plus légers que les conteneurs, mais avec la surcharge d'initialisation et la complexité de seccomp et de cgroups pour garantir une véritable isolation. Cela nécessite une équipe qui comprend profondément le modèle du noyau. Le problème commun à toutes ces approches est qu’elles traitent l’isolation comme quelque chose d’externe : vous construisez une barrière autour du code non fiable à l’aide des mécanismes du système d’exploitation. Wasm inverse cette logique.
Le modèle de capacités : zéro par défaut
Un module WebAssembly démarre avec zéro capacité. Littéralement aucun. Il ne peut pas ouvrir un fichier. Impossible de faire une requête réseau. Impossible de lire les variables d'environnement. Il ne peut accéder à aucun octet en dehors de sa propre mémoire linéaire. Si le module tente l'une de ces opérations sans que l'hôte ait explicitement rendu disponible l'interface correspondante, l'opération échoue — non pas au moment de l'exécution avec une exception, mais structurellement, car la fonction appelée par le module n'existe tout simplement pas dans l'environnement d'exécution.
C’est ce qu’on appelle la sécurité basée sur les capacités, et elle est conceptuellement différente du modèle d’autorité ambiante dont hérite le code natif. Lorsque vous chargez une bibliothèque native, elle s'exécute avec tous les privilèges de processus. Lorsque vous chargez un module Wasm, il démarre sans aucun privilège et vous, en tant qu'hôte, décidez quoi livrer.
L'interface de sécurité se trouve dans le code d'intégration de l'hôte. Vous exposez au module exactement les fonctions qui ont du sens : accès à l'API Figma Canvas, mais pas au système de fichiers ; accès aux données de commande Shopify, mais pas aux informations d'identification de la base de données. Le module fait tout ce que vous lui avez permis de faire, et rien de plus. La surface d’attaque est explicitement indiquée et non déduite.
Comment les vraies plateformes l'utilisent
Figma est l'exemple le plus connu. Le système de plugins exécute chaque plugin dans un bac à sable Wasm. Le plugin a accès à l'API Canvas - il peut lire et modifier des éléments, créer des calques, accéder aux propriétés du texte - mais il n'a accès à rien en dehors de ce contrat. Un plugin ne peut pas lire les fichiers du système d'exploitation ni effectuer d'appels réseau arbitraires. Il ne s’agit pas d’une politique d’utilisation ; C'est une impossibilité technique. C'est pourquoi vous pouvez installer un plugin Figma provenant d'un développeur inconnu avec une certitude raisonnable qu'il n'exfiltrera pas vos fichiers.
Shopify a pris une décision similaire à Shopify Functions : la logique personnalisée pour les remises, la validation du panier et les règles d'expédition est envoyée par les commerçants sous forme de modules Wasm. Chaque appel reçoit les données de la requête, s'exécute dans les limites strictes du processeur et de la mémoire par appel et renvoie le résultat. Un commerçant avec un code mal écrit ne plante pas la plateforme et n'accède pas aux données des autres commerçants.
Envoy Proxy utilise le même modèle pour les filtres de trafic personnalisés. Les entreprises qui utilisent Envoy comme proxy (Istio et AWS App Mesh en sont des exemples) peuvent écrire des filtres Wasm qui traitent les demandes et les réponses en transit. Le filtre a accès aux en-têtes et au corps, mais rien à l'état interne du proxy. Extensibilité sans ouvrir le cœur du système. Les moteurs de jeu sont arrivés au même modèle par des chemins indépendants : les systèmes de modding qui permettent aux joueurs d'ajouter du contenu doivent exécuter le code d'étrangers sans compromettre le jeu hôte, et Wasm résout ce problème avec le même mécanisme de capacités.
Le coût pour ceux qui écrivent des plugins
Cette sécurité a un prix. Écrire un plugin pour une plate-forme basée sur Wasm est plus difficile que d'écrire du JavaScript ou du Python.
La première friction concerne la chaîne d'outils : la compilation pour Wasm nécessite un compilateur compatible : Rust et C/C++ ont un support mature, Go a un support expérimental, Python et Ruby arrivent avec des limitations. Le deuxième est l’accès au système : dans le bac à sable, il n’y a pas d’accès direct à autre chose que ce que l’hôte a exposé. Les bibliothèques qui effectuent des appels HTTP directs ne fonctionnent pas si l'hébergeur n'a pas mis à disposition l'interface correspondante. Cela impose une discipline de conception qui peut être frustrante au début.
Côté plateforme, la complexité réside dans la bonne définition de l’API exposée au module. Une API mal conçue est soit trop restrictive – les plugins ne font pas ce dont ils ont besoin – soit trop permissive, compromettant la sécurité. Ce contrat porte autant sur le produit et la sécurité que sur l'ingénierie.
Quand est-il judicieux d'investir dans ce modèle
La décision a un profil clair. Cela a du sens lorsque vous construisez une plate-forme avec des développeurs externes dont vous ne pouvez pas garantir la qualité du code. Cela est logique lorsque vous avez besoin d'une personnalisation par locataire avec des limites de ressources individuelles : chaque client a sa logique, mais aucun ne monopolise le processeur ou la mémoire. Cela a du sens lorsque vous distribuez du code qui s'exécutera sur une infrastructure que vous ne contrôlez pas entièrement.
Cela n'a aucun sens lorsque les plugins sont internes et que vous faites confiance à l'équipe qui les écrit. La surcharge de la chaîne d'outils et les contraintes du système créent de véritables frictions inégalées lorsque la menace que vous souhaitez atténuer n'existe pas dans votre modèle. L'essentiel est le suivant : l'extensibilité vers l'extérieur, vers un public que vous ne contrôlez pas, est ce que Wasm offre.
A lire aussi
- Infrastructures critiques et dépendance énergétique : ce que les gestionnaires doivent savoir
- Préparation quantique pour les dirigeants : que faire (et ne pas faire) maintenant
- WebAssembly et composants portables : la promesse du modèle de composant -WebAssembly à la périphérie : pourquoi démarrer rapidement et isolément est important
- WebAssembly pour les dirigeants : quand la décision architecturale en vaut la peine
- Authentification des applications : Guide complet de sécurité et d'expérience utilisateur