Contexte et coûts

Dans une société de 500 salariés, le contrat Looker coûte environ 150 000 $ par an pour 300 licences. Trois ingénieurs data passent la majeure partie de leur temps à maintenir Snowflake, un projet dbt de plus de 2 000 modèles, ainsi que l’infrastructure Airflow, Airbyte, DataHub et Kubernetes.

En février, l’un d’eux a développé en une après‑midi un service d’hébergement de fichiers HTML. Huit mois plus tard, le nombre d’utilisateurs hebdomadaires du service égalait voire dépassait celui de Looker, tandis que l’usage de Looker chutait d’un tiers.

Architecture du service HTML

Le service repose sur un bucket S3 où sont stockés les fichiers HTML générés. L’accès est protégé par un SSO interne et le déploiement s’effectue via un module Terraform et un chart Helm, déjà présents dans le cluster Kubernetes de l’entreprise. Une petite application Python, empaquetée comme plugin Claude, pousse les fichiers dans le bucket après génération.

En mars, une API de requête en direct a été ajoutée. Elle utilise le token OAuth Snowflake du visiteur pour exécuter les requêtes, éliminant ainsi la nécessité de créer un modèle d’autorisation dédié. Snowflake conserve son modèle de rôles : si un utilisateur n’a pas le droit de lire la table « sales », le tableau HTML ne pourra pas y accéder.

Intégration de l’IA et du live query

Claude Code (version Opus 4.5) génère des pages HTML contenant graphiques et tableaux. Les utilisateurs, même sans compétences terminal, peuvent demander des analyses via le chatbot, qui renvoie un fichier HTML complet. Le plugin Claude appelle l’API Python pour déposer le fichier, puis le partage via un lien interne.

Le passage du simple fichier statique à un tableau dynamique a été décisif. Le tableau récupère les données en temps réel grâce au token Snowflake, ce qui garantit que les contrôles d’accès restent cohérents entre le data‑warehouse et le tableau affiché.

Modèle de sécurité et limites

Le premier déploiement souffrait d’une faille XSS majeure : chaque tableau s’exécutait sur le même domaine que la session utilisateur, permettant à n’importe quel script Java‑Script d’accéder aux cookies et aux données Snowflake du lecteur. La solution a été de placer chaque tableau dans un iframe sandboxé avec un Content‑Security‑Policy strict. L’iframe ne possède aucun cookie et ne peut communiquer avec le parent que via postMessage, où le parent valide l’expéditeur avant d’appeler l’API Snowflake.

Les jetons de contenu sont limités à une heure et associés à un tableau, un lecteur et un hôte spécifiques, réduisant l’impact d’une éventuelle compromission. Malgré ces mesures, le modèle repose sur la confiance que les utilisateurs ne publieront pas de code malveillant, car la révision manuelle a été volontairement exclue pour préserver la rapidité d’utilisation.

En résumé, le remplacement de Looker par un service interne d’HTML montre que, avec une architecture cloud native (S3, Kubernetes, Terraform) et une intégration fine des rôles Snowflake, il est possible de fournir des tableaux plus flexibles et visuellement attractifs. Cependant, la liberté d’injection HTML impose un modèle de sécurité robuste basé sur l’isolation des iframes et des jetons à durée limitée, sans quoi le produit devient une porte d’entrée XSS à grande échelle.