Accueil / Blog / Gouvernance et IA
Gouvernance et IA
Vos agents IA voient exactement ce que l'utilisateur a le droit de voir
Un agent IA qui interroge vos données a besoin d’un compte pour se connecter. Dans la plupart des montages que nous voyons, ce compte est unique, technique, et large. Tous les agents, tous les utilisateurs, tous les prompts lisent alors avec les mêmes droits. La question « cet utilisateur a-t-il le droit de voir cette colonne ? » n’est plus posée au moteur de données ; elle est déléguée, sans le dire, au modèle de langage et à son prompt système.
Nous pensons que c’est le mauvais endroit pour la poser. Nous publions aujourd’hui akko-mcp-trino, un serveur MCP pour Trino qui remet la question là où elle a toujours été tranchée : dans le moteur, sous l’identité de la personne pour qui l’agent travaille.
Le problème, concrètement
Prenez une table de clients avec une colonne d’emails, un filtre par pays pour les analystes et un masque sur les emails pour tout le monde sauf les administrateurs. Votre BI le respecte. Vos notebooks le respectent. Vos requêtes SQL le respectent, parce que Trino demande à OPA ou à Ranger avant chaque lecture, et que ces moteurs connaissent l’utilisateur.
Branchez maintenant un agent avec un compte technique. Le filtre par pays disparaît. Le masque disparaît. Et ce qui les remplace, c’est une phrase dans un prompt système qui dit au modèle de ne pas montrer les emails. Une injection de prompt, un utilisateur insistant, ou simplement un modèle qui interprète mal une consigne, et la table sort entière.
Ce n’est pas un problème de modèle. C’est un problème d’identité : le moteur ne sait plus pour qui il travaille.
Ce que fait akko-mcp-trino
Le serveur reçoit, à chaque appel d’outil, le jeton de l’utilisateur, celui que votre fournisseur d’identité lui a délivré en se connectant. Il vérifie la signature contre les clés publiques du fournisseur, l’émetteur, l’audience, l’expiration. Il en tire le sujet. Et il exécute la requête dans Trino avec ce sujet en X-Trino-User.
À partir de là, rien de nouveau ne se passe, et c’est tout l’intérêt. Trino interroge son moteur de politique comme il le fait pour n’importe quel client. Le filtre par pays s’applique. Le masque s’applique. Le périmètre de catalogues s’applique. L’agent reçoit ce que l’utilisateur aurait obtenu en tapant la requête lui-même.
Le serveur ne décide jamais l’accès. Il ne connaît pas vos règles, et ne veut pas les connaître. Mettre de la politique dans un serveur intermédiaire, c’est la dupliquer, puis, un jour, la contredire.
La même question, deux réponses
Nous avons fait tourner un modèle Mistral sur ce serveur, avec un agent de quatre-vingts lignes qui lui expose les outils. Même question, même serveur, même modèle, deux jetons.
Le modèle ne savait pas que carol était restreinte. Il n’y avait rien à ce sujet dans son prompt. Il a exploré le catalogue, décrit la table, écrit la même requête SQL dans les deux cas, et rendu ce que Trino lui a donné.
Ce qu’il y a autour
Porter l’identité ne suffit pas à faire un serveur qu’on peut exposer à des agents. Quelques choses que nous avons ajoutées, parce que nous en avions besoin nous-mêmes.
Deux principaux, pas un. Une clé d’espace de travail Cursor ou Claude n’est pas un utilisateur. Le serveur distingue le produit qui appelle (X-Agent-Key, pour les quotas et l’audit) de la personne pour qui il appelle (le jeton). Un produit non enregistré est refusé avant même qu’on lise le jeton.
Lecture seule décidée sur l’arbre syntaxique. Un contrôle par mot-clé de tête laisse passer WITH w AS (DELETE FROM t) SELECT 1. Le serveur analyse la requête et refuse une écriture où qu’elle se trouve, CTE et sous-requêtes compris.
Découverte standard. Le serveur publie ses métadonnées RFC 9728 et met un WWW-Authenticate sur chaque refus, pour que Cursor, Claude ou VS Code sachent où envoyer l’utilisateur se connecter.
Un identifiant de requête et une ligne d’audit par appel. Outil, sujet, produit, identifiant du jeton, résultat. Jamais le jeton lui-même : la structure de la ligne n’a pas de champ pour le contenir.
Quotas et révocation. Par utilisateur et par produit ; et, en option, une interrogation du fournisseur d’identité pour refuser un jeton révoqué avant son expiration. Si le fournisseur ne répond pas, le serveur refuse. « Inconnu » n’est pas « encore valide ».
Ce que les preuves nous ont appris
Nous ne faisons pas confiance à une suite de tests unitaires verte. Deux cents tests à cent pour cent de couverture, c’est nécessaire, pas suffisant. Trois scripts rejouables tournent contre un cluster réel, Trino derrière Keycloak et OPA, sans rien redéployer.
Le premier vérifie les gardes une à une et la démonstration à deux comptes. Le deuxième est adverse : deux utilisateurs sur quatre sessions chacun, trois appels par session, tous en même temps, sur les deux transports MCP ; écritures, instructions empilées, injections dans les identifiants, jetons signés par une autre clé, jetons expirés, en-tête X-Trino-User forcé par l’utilisateur restreint. Le troisième fait piloter le serveur par un modèle.
Le deuxième a trouvé un vrai défaut avant la publication. La garde de lecture seule était testée, verte, et fausse : elle regardait le nœud racine de l’arbre, et un DELETE dans un CTE passait. Trino le refusait ensuite comme erreur de syntaxe, ce qui n’est pas une protection. Le troisième en a trouvé un autre, plus humble : les modèles terminent leur SQL par un point-virgule, Trino le refuse, et l’agent a relancé douze fois la même requête. Le serveur retire maintenant ce point-virgule.
Si nous avions publié après les tests unitaires, ces deux défauts seraient sortis avec le code.
Où ça s’installe
N’importe où il y a un Trino et un fournisseur OIDC. Trino 351 et suivants, testé sur 483. OPA, Ranger ou le contrôle d’accès fichier de Trino pour décider. Keycloak, Entra ID, Okta ou tout autre fournisseur qui publie un JWKS. Un pip install akko-mcp-trino, six variables d’environnement, et une ligne dans le mcp.json de l’hôte.
Le code est sous licence Apache 2.0, sur github.com/AKKO-p/akko-mcp-trino. La documentation donne les prérequis, la configuration complète et le détail des preuves.
Pourquoi nous le publions
AKKO construit des briques d’accès gouverné pour les agents, sur les moteurs et les annuaires que les entreprises ont déjà. Celle-ci est la première, et la plus simple à expliquer : l’agent apporte l’identité, le moteur décide. Les suivantes s’occuperont de l’échange de jetons entre fournisseurs, de la synchronisation des politiques depuis le catalogue, et de la mesure. Nous les publierons de la même manière, avec leurs preuves.
Si vous faites tourner Trino derrière Ranger ou OPA et que vous voulez mettre une identité devant vos agents, le serveur est prêt. Si quelque chose ne marche pas chez vous, ouvrez un ticket ; c’est ainsi qu’il s’améliorera.
Essayer akko-mcp-trino
pip install akko-mcp-trino · Documentation · Code source