Sécuriser les agents IA avec les outils MCP de Laravel
Donner à un agent IA l'accès à votre application via MCP, c'est comme donner un trousseau de clés à quelqu'un. Si vous ne définissez pas de règles, il pourrait ouvrir les mauvaises portes.
J'ai récemment conçu des outils MCP pour une application Laravel multi-tenant. Mon objectif était simple : permettre à l'agent de piloter l'application sans lui permettre de voir les données d'un autre utilisateur.
Le problème avec les outils MCP
Chaque outil MCP est un endpoint. Un agent appelle un outil, et votre serveur exécute du code. Dans une application multi-tenant, chaque outil doit répondre à deux questions :
- Avez-vous l'autorisation de faire cela ?
- Avez-vous l'autorisation de le faire dans cette organisation spécifique ?
Si vous en oubliez une, vous provoquez une fuite de données.
Pourquoi le multi-tenancy standard échoue ici
Dans une application web classique, vous utilisez des sessions. Vous utilisez des global scopes pour filtrer les données par ID d'organisation. Cela fonctionne parce que l'« organisation actuelle » est toujours présente dans la session.
Les outils MCP n'utilisent pas de sessions. Ils utilisent des tokens. Il n'y a pas de middleware pour définir le contexte du tenant. Si vous vous reposez sur un global scope qui recherche une session, il ne trouvera rien. Il pourrait alors retourner toutes les lignes de votre base de données. C'est une fuite de données silencieuse.
La solution : un filtrage explicite
Ne vous reposez jamais sur un scope ambiant avec une authentification par token. Filtrez explicitement à chaque fois.
J'ai créé un trait unique pour gérer cela :
trait ResolvesOrgEvents
{
protected function resolveOrgEvent(Authenticatable $user, string $uuid): ?Event
{
if (empty($user->organization_id)) {
return null;
}
return Event::query()
->withOrganization($user->organization_id)
->where('uuid', $uuid)
->first();
}
}
Cette approche suit quatre règles :
- Utilisez des UUID : N'utilisez jamais d'ID auto-incrémentés. Les agents ne doivent pas pouvoir deviner les ID en changeant un chiffre.
- Source unique de vérité : Le filtre d'organisation est centralisé dans un seul trait. Chaque outil l'utilise.
- Réutilisez les permissions : N'inventez pas de nouvelles permissions pour les agents. Utilisez les mêmes chaînes de permissions que votre application web. Cela empêche l'agent d'avoir plus de pouvoir que l'utilisateur humain.
- Marquez les effets de bord : Utilisez des annotations pour indiquer si un outil est en lecture seule ou s'il permet l'écriture.
Tester les limites
Vous devez tester le scénario d'échec (negative path). Ne vous contentez pas de tester si l'outil fonctionne. Testez qu'un utilisateur de l'Organisation A ne peut pas voir les données de l'Organisation B.
Si un agent tente d'accéder à un UUID appartenant à un autre tenant, l'outil doit renvoyer « non trouvé ». Il ne doit pas dire à l'agent que la donnée existe mais appartient à quelqu'un d'autre.
Considérez chaque outil d'IA comme un endpoint non fiable. La discipline est le seul moyen de garder vos données en sécurité.
