Aller au contenu

Le moindre privilège pour une machine qui improvise

Éditorial

Un agent IA doté d'un shell, d'un accès aux fichiers et de clés d'API est un acteur du système d'information, pas un outil. Le moindre privilège classique suppose qu'on sait d'avance ce que le programme va faire ; l'agent ne le sait pas lui-même, et c'est son environnement qu'il faut borner, pas ses intentions.

Mis à jour le 25 septembre 2026~26 min de lecture13 sections

→ Lire l’explication complète de la marmotte

L’éditorial précédent s’achevait sur une question qu’il avait soigneusement contournée pendant quatre mille mots, ce qui est une performance dont je ne suis pas peu fier : qu’est-ce qui écrit le journal ? Réponse : un agent. Un programme qui lit vos dépôts, exécute vos commandes, appelle vos API et produit des fichiers. Ce n’est pas un outil au sens où l’est un éditeur de texte, qui a la décence de ne rien faire tant qu’on ne lui a rien demandé. C’est un acteur. Il décide, il enchaîne, il modifie l’état du système. Et nous l’avons fait entrer dans le système d’information par la porte la plus large qui soit : celle de l’utilisateur qui l’a lancé.

C’est la configuration par défaut de presque tous les agents de développement et d’administration. L’agent tourne dans le terminal de quelqu’un, sous son compte, avec ses variables d’environnement, ses clés SSH chargées, ses jetons d’API posés dans des fichiers de configuration, ses sessions ouvertes vers le cloud. Il hérite de tout. Personne n’a décidé qu’il hériterait de quoi que ce soit ; il y a eu une commande d’installation, un premier prompt, et un testament que nul n’a jamais lu.

La réaction naturelle du professionnel de la sécurité, devant ce spectacle, est de sortir de sa poche le principe le plus ancien et le moins contesté de la discipline : le moindre privilège. Donner à l’agent les droits nécessaires à sa tâche, et rien de plus. C’est la bonne intuition. C’est aussi l’endroit précis où les ennuis commencent.

Le moindre privilège, tel qu’on l’applique depuis toujours, suppose qu’on sait ce que le programme va faire. Or l’agent ne le sait pas lui-même avant de l’avoir fait. Son comportement n’est pas écrit dans son code : il se compose à l’exécution, à partir d’une consigne, de ce qu’il lit en chemin, et d’un modèle statistique dont personne ne peut énumérer les sorties, pas même ceux qui le vendent, surtout pas ceux qui le vendent. Appliquer le principe sans l’adapter produit l’un de deux échecs : un agent inutilisable parce que tout lui est interdit, ou un agent à qui l’on a « temporairement » tout ouvert. En informatique, le temporaire est la forme la plus aboutie du définitif.

Cet éditorial soutient qu’il existe une troisième voie, au prix d’un déplacement de la question. On ne peut pas borner ce que l’agent veut faire. On peut borner ce qu’il peut faire, là où il le fait, et sous quel nom.

Le principe est formulé classiquement par Saltzer et Schroeder, au milieu des années 1970, dans leur article sur la protection de l’information : chaque programme et chaque utilisateur devrait opérer avec le plus petit ensemble de privilèges nécessaire à sa tâche. L’énoncé est si évident qu’on oublie ce qu’il présuppose, comme on oublie que « rouler à droite » présuppose une route.

Il présuppose d’abord que la tâche est connue. Un service de sauvegarde lit des fichiers et écrit dans un dépôt ; un serveur web lit un répertoire et écoute sur un port. Quelqu’un peut écrire la liste des actions légitimes avant la première exécution, parce que cette liste découle du code.

Il présuppose ensuite que le comportement est stable. Le serveur web ne décide pas un mardi, sur un coup de tête, d’ouvrir une connexion vers un hôte inconnu. S’il le fait, c’est une anomalie, donc un signal. Toute la détection comportementale repose sur cette bienheureuse monotonie.

Il présuppose enfin que les entrées sont des données. Le serveur reçoit des requêtes, pas des conseils sur la conduite de sa vie. Quand une entrée parvient à se faire traiter comme une instruction, on appelle cela une injection, et c’est une vulnérabilité, précisément parce que l’architecture était censée garantir la séparation.

Un agent viole les trois, et il les viole par construction.

La tâche n’est pas connue : « corrige le test qui échoue » peut exiger de lire trois fichiers, ou d’installer une dépendance, ou de réécrire la configuration du système de construction, ou de lancer une base de données. L’agent découvre la tâche en l’exécutant ; c’est tout son intérêt. Si l’on pouvait énumérer les étapes à l’avance, on écrirait un script, et on dormirait mieux.

Le comportement n’est pas stable : deux exécutions du même prompt sur le même dépôt peuvent emprunter des chemins différents. La notion même de « normal » devient floue, et la détection par écart avec elle.

Les entrées sont des instructions. C’est le point décisif. Un modèle de langage ne dispose d’aucun canal séparé pour les ordres et pour les données : tout arrive sous forme de texte dans la même fenêtre de contexte. Le contenu d’un fichier, la réponse d’une API, le README d’une dépendance entrent dans le même flux que la demande de l’utilisateur, et le modèle n’a qu’une capacité statistique, donc imparfaite, à distinguer ce qu’on lui demande de ce qu’il lit. Cinquante ans d’efforts pour séparer le code des données, et nous voici ravis d’avoir inventé une machine qui les confond avec enthousiasme.

On pourrait conclure que le principe est inapplicable. Ce serait trop commode. Il est inapplicable au niveau de la tâche. Il reste parfaitement applicable au niveau de l’environnement, à condition d’accepter que celui-ci soit défini non par ce que l’agent fera, mais par ce qu’on accepte qu’il puisse faire de pire.

L’informatique a un nom ancien pour le programme qui dispose de privilèges légitimes et se fait manipuler pour les exercer au profit d’un tiers : le député confus. Le problème a été décrit à la fin des années 1980, à propos d’un compilateur autorisé à écrire dans un fichier de facturation, qu’un utilisateur pouvait amener à écraser ce fichier en lui désignant le bon nom de sortie. Le compilateur ne faisait rien d’illégal au regard de ses droits. Il servait simplement quelqu’un qui n’en avait pas, sans pouvoir faire la différence. Il y a dans les administrations beaucoup de députés confus ; il y en a désormais dans les terminaux.

L’agent doté d’outils en est une variante bavarde, et c’est ce qui rend l’injection indirecte si sérieuse. L’agent reçoit une tâche légitime. Pour l’accomplir, il lit du contenu dont l’utilisateur n’est pas l’auteur : une page web, un ticket rédigé par un client, un commentaire dans une dépendance, un courriel. Ce contenu contient une phrase formulée comme un ordre. Le modèle peut la suivre. Et quand il la suit, il le fait avec les privilèges de l’utilisateur, puisque c’est sous ce compte qu’il tourne.

L’attaquant n’a donc besoin d’aucun accès. Il lui suffit de placer du texte là où l’agent ira lire. La surface d’attaque d’un agent n’est pas son interface : c’est tout ce qu’il est susceptible de lire. Autant dire qu’elle a la taille d’Internet, avec la bonne foi qu’on lui connaît.

Toute injection n’est pas grave. Ce qui transforme une phrase parasite en incident, c’est la réunion de trois propriétés dans le même agent, au même moment :

  • un accès à quelque chose qui a de la valeur : code privé, secrets, données personnelles, droit de modifier une infrastructure ;
  • une exposition à du contenu non maîtrisé : n’importe quel texte dont l’auteur n’est pas de confiance ;
  • un canal vers l’extérieur : réseau, publication, message, demande de fusion, ou simple écriture dans un endroit que l’attaquant peut lire.

Réunies, elles permettent l’exfiltration sans la moindre vulnérabilité logicielle au sens classique. L’agent lit le secret parce qu’il en a le droit, lit l’instruction parce qu’on lui a demandé de lire ce document, et envoie le secret parce qu’il dispose d’un outil pour cela. Aucune étape n’est anormale. Le crime parfait, commis par un employé modèle.

D’où la conclusion la plus utile de cet éditorial : on ne protège pas un agent en espérant qu’il résistera à l’injection, on le protège en retirant au moins une des trois propriétés. Qui lit du contenu public et touche des secrets n’a pas de réseau. Qui a besoin du réseau et de contenu externe ne voit aucun secret. Qui manipule du sensible avec un accès sortant ne lit que du contenu d’origine maîtrisée, ce qui est plus rare qu’on ne croit.

Avant de parler de périmètre, il faut régler une question que presque tous les déploiements escamotent : qui est l’agent, du point de vue du système ?

Par défaut, il est l’utilisateur. Pour le serveur Git, l’agent qui pousse une branche est indiscernable du développeur. Pour le fournisseur de cloud, son appel d’API porte la même identité que celui de l’humain. Pour les journaux, il n’existe pas. C’est un fantôme qui signe avec votre stylo.

Cette confusion a trois conséquences, dont chacune suffirait.

Elle rend le périmètre impossible à définir. On ne restreint pas les droits de l’agent sans restreindre ceux de l’humain, puisque ce sont les mêmes. Toute réduction se paie en productivité humaine, donc ne se fait pas.

Elle rend l’imputation impossible. Le jour où une ressource a disparu, la question « l’humain ou l’agent ? » n’a pas de réponse dans les journaux du système cible. Elle en a peut-être une dans le transcript local, s’il existe encore, s’il est intègre, et si quelqu’un pense à le chercher : trois conditions, soit deux de trop.

Elle fausse la responsabilité. L’humain devient comptable d’actions qu’il n’a ni formulées ni vues. Il a demandé qu’on range la cuisine ; on lui reproche d’avoir vendu le buffet.

La correction est simple à énoncer : l’agent doit disposer d’une identité propre, distincte de celle de l’humain, reconnaissable par chaque système qu’il touche. Un compte de service dédié sur le serveur Git. Un rôle distinct dans l’IAM du fournisseur de cloud. Un jeton émis pour lui, avec sa propre portée. Un nom qui apparaît dans les journaux.

Identité propre ne veut pas dire identité autonome. L’agent agit pour quelqu’un, et cela doit rester visible. La bonne forme est la délégation : l’identité de l’agent porte la trace de l’humain qui l’a mandaté, pour une tâche, pendant une durée. Le système cible voit à la fois « c’est l’agent » et « pour le compte d’untel ».

Des mécanismes existants permettent d’en approcher : jetons à courte durée émis à la demande, échanges de jetons qui réduisent la portée à chaque étape, rôles assumés avec un nom de session qui identifie la tâche. Aucun n’a été conçu pour les agents, et la normalisation d’une identité d’agent est un chantier ouvert dont je me garderai de prédire l’issue ; à mon âge, on a vu trop de standards définitifs finir en note de bas de page. Le principe, lui, ne dépend pas de l’outillage : un identifiant par agent et par tâche, émis pour peu de temps, jamais celui de l’humain.

La durée compte autant que la portée. Un jeton qui expire avec la tâche borne la fenêtre d’une injection réussie. Un jeton permanent dans un fichier de configuration offre la même fenêtre à tout ce qui passera par là pendant des mois, avec la constance d’un paillasson.

Le périmètre : raisonner en capacités, pas en commandes

Section intitulée « Le périmètre : raisonner en capacités, pas en commandes »

Une fois l’agent nommé, on peut lui attribuer des droits. La tentation est de lister ce qu’il a le droit de faire, commande par commande. C’est ce que proposent spontanément les interfaces d’agent, sous forme de listes de commandes autorisées. Utile comme garde-fou ergonomique. Sans valeur comme frontière de sécurité.

Un shell n’est pas un outil parmi d’autres : c’est l’outil qui contient tous les autres. Autoriser python, c’est autoriser n’importe quel programme. Autoriser find, c’est autoriser l’exécution arbitraire via -exec. Autoriser git, c’est autoriser les hooks du dépôt et les commandes passées en configuration. Autoriser npm install, c’est exécuter les scripts d’installation de chaque paquet, écrits par des inconnus dont on ne sait rien sinon qu’ils ont un clavier. Autoriser make, c’est obéir au Makefile. La liste des commandes « inoffensives » qui permettent tout est longue, et connue de quiconque a tenté de bâtir un shell restreint, c’est-à-dire d’une petite confrérie de gens désabusés.

Filtrer les commandes par leur texte, c’est filtrer une injection SQL par une liste de mots interdits : on arrête les maladroits, on laisse passer les autres, et on se sent protégé, ce qui est le pire des trois.

La bonne unité est la capacité : ce que le processus peut atteindre, quelle que soit la manière dont il s’y prend. Trois capacités concentrent l’essentiel du risque, et chacune se borne hors de l’agent.

Le système de fichiers. Un agent qui travaille sur un projet doit lire et écrire ce projet. Il n’a aucun besoin de ~/.ssh, du trousseau du navigateur, de la configuration des clients cloud, ni des autres projets. Ce qu’il ne voit pas, il ne peut ni le divulguer ni l’abîmer, quelle que soit la prose qu’il a lue.

Le réseau. C’est la capacité la plus sous-estimée, parce qu’elle conditionne l’exfiltration. Un agent sans réseau peut se tromper ; il ne peut pas envoyer vos secrets à un inconnu. S’il lui faut un registre de paquets, il n’aura que ce registre, ou mieux un miroir interne, via un mandataire qui refuse le reste. C’est la segmentation réseau appliquée à un processus : refus par défaut, ouverture explicite.

Les identifiants. Variables d’environnement, fichiers d’identification, agent d’authentification joignable par un socket. L’agent ne devrait disposer que des identifiants émis pour lui et pour sa tâche, injectés au plus près de l’usage plutôt que traînant dans tout l’environnement comme des clés sous le pot de fleurs.

Les protocoles d’outillage comme MCP proposent une alternative au shell : des outils nommés, typés, aux paramètres déclarés. C’est un progrès réel en lisibilité. Cela ne change pas la nature du problème. Un outil « exécuter une requête SQL » est un shell de base de données. Un outil « lire une URL » est un canal de sortie, puisque l’URL peut porter des données. Un serveur d’outils tiers est une dépendance qui s’exécute avec les droits qu’on lui donne, et dont les descriptions d’outils entrent elles aussi dans le contexte du modèle, donc peuvent contenir des instructions.

La granularité de l’interface n’est pas la granularité du privilège. Un outil étroit adossé à des droits larges reste un accès large, simplement mieux élevé.

Si le périmètre se définit en capacités, il doit être appliqué par quelque chose que l’agent ne contrôle pas. Le mot usuel est bac à sable, et il désigne des réalités fort diverses.

Le plus faible est celui que l’agent s’applique à lui-même : le client qui demande confirmation avant certaines commandes, ou refuse d’écrire hors du répertoire courant. Précieux contre les erreurs, presque sans valeur contre une instruction malveillante, parce qu’il réside dans le même processus que le comportement qu’il encadre. C’est le prévenu qui tient lui-même le registre de ses sorties.

Le bac à sable réel est imposé par le système d’exploitation : espaces de noms et conteneurs, machine virtuelle, compte système sans droits, contrôle d’accès obligatoire. Peu importe la technologie ; ce qui compte, c’est que la frontière soit tenue par le noyau ou l’hyperviseur, pas par du code que l’agent exécute. Par exemple, un conteneur sans privilèges ni réseau, où seul le projet est monté :

Fenêtre de terminal
# Conteneur jetable : pas de réseau, racine en lecture seule,
# aucune capacité noyau, pas d'élévation possible. Seul le projet est visible.
podman run --rm -it \
--network=none \
--read-only --tmpfs /tmp \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--userns=keep-id \
-v "$PWD":/work:Z -w /work \
image-de-l-agent

Rien d’exotique là-dedans, et c’est le point. Le répertoire personnel n’existe pas pour le processus. Aucune clé, aucun jeton n’y est visible. Aucun paquet ne sort. S’il faut un registre, on remplace --network=none par un réseau dont la seule issue est un mandataire filtrant ; s’il faut un identifiant, on l’injecte pour la durée de la tâche.

Le caractère jetable est une propriété de sécurité

Section intitulée « Le caractère jetable est une propriété de sécurité »

Un bac à sable recréé à chaque tâche n’accumule rien : pas de secret oublié dans un fichier temporaire, pas de configuration modifiée la veille, pas de hook glissé en douce dans un dépôt local. L’état persistant est la mémoire de l’attaquant. Un environnement amnésique l’oblige à tout recommencer à chaque fois, ce qui est la seule forme d’oubli que la sécurité ait jamais encouragée.

Encore faut-il que le produit du travail sorte par un chemin explicite et contrôlé : un correctif, une branche, une demande de fusion. On retrouve la logique de l’éditorial précédent, promouvoir plutôt que conserver : ce qui compte change de lieu en passant un point de contrôle, et le reste est détruit sans oraison funèbre.

Même borné, un agent aura parfois besoin de faire quelque chose de grave : supprimer, pousser en production, écrire à l’extérieur, modifier des droits, dépenser de l’argent. La réponse habituelle est la confirmation humaine. L’agent propose, l’humain dispose. C’est une bonne réponse, à une condition qu’on respecte rarement : la confirmation doit être rare pour avoir un sens.

Une confirmation demandée vingt fois par heure n’est plus une décision, c’est un réflexe rotulien. L’humain clique « oui » parce que les dix-neuf précédentes étaient anodines, et la vingtième passe avec les autres. Tous ceux qui ont conçu des boîtes d’avertissement le savent : un avertissement fréquent apprend à ne pas le lire. Les interfaces qui réclament une approbation pour chaque lecture de fichier obtiennent l’effet inverse de celui recherché, puis sont désactivées par des utilisateurs excédés, ce qui est pire que de n’en avoir jamais eu.

Il faut trier. Le critère que je retiens n’est pas la dangerosité supposée de la commande, indécidable à partir de son texte, mais la réversibilité de son effet :

  • réversible et local (modifier un fichier suivi par Git dans le bac à sable, lancer des tests) : pas de confirmation, le bac à sable et le gestionnaire de versions suffisent ;
  • réversible mais visible (ouvrir une demande de fusion, commenter un ticket) : confirmation légère ou journalisation seule ;
  • irréversible ou externe (supprimer sans sauvegarde vérifiée, modifier des droits, publier, envoyer hors de l’organisation, dépenser, toucher la production) : confirmation obligatoire, jamais contournable par l’agent lui-même.

L’humain doit valider ce qui va se passer, pas ce que l’agent dit qu’il va faire. « Je vais nettoyer les ressources de test inutilisées » est une intention, et toutes les catastrophes de l’histoire ont commencé par une intention louable. La liste exacte des ressources, avec leurs identifiants, est un effet. Seul l’effet se valide. Faire approuver un résumé rédigé par l’agent, c’est demander au contrôleur de faire confiance au contrôlé sur parole.

D’où un schéma en deux temps : l’agent produit un plan concret (un diff, une liste de commandes, le plan d’un outil d’infrastructure déclarative), l’humain le valide, puis l’exécution se fait avec des capacités limitées à ce plan, idéalement par un composant qui n’est pas l’agent. Le « planifier puis appliquer » est devenu banal dans l’infrastructure ; il se transpose remarquablement bien.

Mieux encore : concevoir pour la réversibilité. Instantanés avant opération, suppression douce avec délai de purge, branches plutôt que modifications directes, préproduction qui reçoit tout d’abord. Chaque mesure fait passer une action de la colonne « irréversible » à la colonne « réversible », et économise une confirmation, donc un peu de l’attention humaine, cette ressource non renouvelable.

Un agent produit beaucoup de texte sur ce qu’il fait. Ce texte n’est pas un journal. C’est un récit, rédigé par l’acteur lui-même, qui peut être incomplet, inexact ou orienté par une instruction suivie en route. En cas d’incident, on ne reconstitue pas les faits à partir des mémoires du suspect, si bien écrites soient-elles.

La journalisation utile se fait au point d’application, par des composants que l’agent ne contrôle pas : le mandataire réseau qui note les destinations contactées, l’IAM qui note les appels émis sous l’identité de l’agent, la plateforme Git qui note les poussées de son compte de service, l’hôte qui note les processus lancés dans le bac à sable. Ces traces décrivent ce qui s’est passé, et non ce que l’agent a cru ou voulu dire.

C’est là que l’identité propre paie. Avec elle, chaque journal existant devient une trace de l’agent sans le moindre développement. Sans elle, il faut reconstruire l’imputation par corrélation d’horodatages entre un transcript local et des journaux distants, exercice fragile, lent, et donc jamais fait. L’observabilité ne se décrète pas après l’incident ; elle dépend de choix de nommage faits bien avant.

Deux précautions complètent le tableau. Journaliser les entrées autant que les actions : une injection se comprend en retrouvant ce que l’agent a lu juste avant d’agir, donc la provenance des contenus consommés (fichier, URL, réponse d’outil) doit être notée. Traiter ce journal comme sensible : il contient des fragments de tout ce que l’agent a touché. C’est le problème de l’éditorial précédent, qui ne disparaît pas parce qu’on a déménagé la journalisation. Les problèmes ont ceci de commun avec les meubles qu’ils suivent dans les déménagements.

Il serait malhonnête de conclure sans donner la parole à la défense. Elle tient en une phrase : un agent bridé est un agent inutile, et un agent inutile sera contourné.

L’argument n’est pas paresseux. Ce qui rend un agent précieux, c’est justement sa capacité à traverser les frontières que les outils classiques respectent : lire le code, lancer les tests, consulter la documentation en ligne, installer ce qui manque, vérifier le résultat dans l’environnement réel. Chaque capacité retirée coupe un chemin de résolution. Sans réseau, pas de documentation. Sans identifiants, pas de test d’intégration. Avec une confirmation à chaque étape, l’agent consomme plus d’attention humaine qu’il n’en économise, et l’on a réinventé le stagiaire, en plus cher.

Et l’on sait ce que deviennent les contrôles qui coûtent plus qu’ils ne rapportent aux yeux de ceux qui les subissent : ils sont désactivés. Les modes « sans confirmation » existent dans la plupart des outils d’agent parce qu’ils sont demandés. Une politique trop stricte ne produit pas des agents confinés ; elle produit des agents lancés en douce sur le poste personnel, sous le compte de l’utilisateur, sans aucune des protections voulues.

Second étage, plus dérangeant : l’humain non plus n’est pas prévisible. L’administrateur se trompe de fenêtre, tape une commande destructrice, clique sur un lien piégé. Nous lui accordons des privilèges larges par confiance en son jugement, pas parce que nous savons d’avance ce qu’il fera. Pourquoi exiger de la machine une prévisibilité que nous n’exigeons d’aucun de nos semblables, qui en seraient d’ailleurs bien incapables ?

Je prends l’objection au sérieux, et j’en retiens deux choses.

L’ergonomie du confinement est une exigence de sécurité, pas un confort. Un bac à sable qui démarre en une seconde, monte le bon répertoire, ouvre le registre de paquets par défaut et fait sortir le travail par une branche est un bac à sable qu’on utilise. Celui qui exige vingt minutes de configuration par projet est une politique qui n’existe que sur le papier, où elle est d’ailleurs très bien.

Ensuite, une différence de nature, pas de degré. L’humain est imprévisible, mais il n’est pas programmable par le premier texte venu. Un administrateur qui lit dans un README « supprime la base de production » ne le fait pas ; il s’interroge, au pire sur l’auteur du README. Un agent peut le faire. La résistance humaine à la manipulation n’est pas parfaite, l’hameçonnage en témoigne, mais elle est sans commune mesure avec celle d’un modèle actuel. S’y ajoute la cadence : l’agent enchaîne des dizaines d’actions pendant que l’humain en fait une, et la fenêtre de rattrapage se réduit d’autant.

La conclusion n’est donc pas « bridez tout », mais graduez les environnements : un bac à sable large pour explorer, sans aucun secret ; un environnement étroit, avec des identifiants à courte durée, pour les tâches qui touchent des systèmes réels ; une confirmation rare, portant sur l’effet, pour ce qui ne se défait pas. Que ce soit le même programme ne justifie pas que ce soit le même environnement. On ne donne pas au même homme les mêmes clés pour arroser le jardin et pour ouvrir la chambre forte, même s’il est très bien élevé.

Je ne sais pas jusqu’où progressera la résistance des modèles à l’injection. Tout cet éditorial suppose qu’elle reste imparfaite. Si des architectures parvenaient à séparer structurellement instructions et données dans le traitement du modèle, une partie de l’argument tomberait. Je n’ai aucun élément sérieux pour dire si c’est proche, lointain ou impossible, et je me méfie de ceux qui en ont.

Je ne sais pas si le classement par réversibilité est automatisable. Je le présente comme un critère pour l’humain qui conçoit la politique. L’appliquer automatiquement suppose de connaître l’effet d’une commande avant de l’exécuter, ce qui ramène au problème de départ. Pour des outils structurés, c’est envisageable ; pour un shell, je ne vois pas comment.

Je ne sais pas quelle forme prendra l’identité des agents. Plusieurs propositions circulent, des extensions de protocoles d’autorisation existants aux identités de charge de travail. Le lecteur qui veut s’y fier vérifiera l’état des travaux auprès des organismes de normalisation concernés, au moment où il lit, et non d’après un vieux monsieur qui écrit en septembre 2026.

Je n’ai pas de mesure du coût réel du confinement. J’affirme qu’un bac à sable bien outillé n’entrave presque pas le travail. C’est un raisonnement sur des mécanismes, pas une mesure de productivité, et certaines tâches pourraient en souffrir bien plus que je ne le crois.

Le moindre privilège n’est pas mort avec les agents. Il a changé d’objet. On ne peut plus le calculer à partir de la tâche, puisque la tâche se découvre en s’exécutant. On peut encore le calculer à partir de l’environnement, à condition de changer de question : non plus « que doit faire ce programme ? », mais « qu’est-ce que j’accepte qu’il puisse faire de pire ? ».

Quatre choses me paraissent acquises. Un agent doit avoir une identité à lui, faute de quoi aucun droit ne peut être restreint et aucune action imputée. La frontière se tient hors de l’agent, dans le noyau, l’hyperviseur, le mandataire réseau et l’IAM, jamais dans des consignes adressées au modèle ni dans des listes de commandes. L’accès aux secrets, l’exposition à du contenu non maîtrisé et la sortie vers l’extérieur ne doivent jamais être réunis au même endroit. Et la confirmation humaine est une ressource rare, à réserver à l’irréversible et à faire porter sur l’effet, jamais sur le récit.

Reste une asymétrie que rien de tout cela ne corrige. Nous savons borner ce qu’un programme touche. Nous ne savons pas borner ce qu’il comprend de travers. Un agent parfaitement confiné peut encore produire un correctif faux, plausible, et approuvé par un humain fatigué un vendredi à dix-huit heures. Cela ne relève plus du contrôle d’accès mais de la relecture, discipline ingrate qui concerne autant les agents que ceux qui les surveillent, et dont je remarque avec une certaine mélancolie qu’on ne l’a jamais vendue sous forme d’abonnement.

Un agent lancé sous le compte de son utilisateur, sans bac à sable ni identité propre, transforme chaque document qu’il lit en commande potentielle exécutée avec tous les droits de cet utilisateur, clés SSH, jetons cloud et accès aux dépôts compris. Une instruction glissée dans un ticket ou une dépendance suffit alors à faire sortir un secret par un outil parfaitement légitime, sans exploit ni alerte, puisque chaque étape est autorisée. La réponse à l’incident bute ensuite sur la même confusion : impossible de couper l’agent sans couper l’humain, si bien que révoquer ses jetons revient à arrêter le travail du développeur, et que chaque clé chargée dans sa session doit être tenue pour exposée. L’enquête, elle, commence par soupçonner la seule personne qui n’a rien fait.

Un agent est un programme qui s’appuie sur un modèle de langage, c’est-à-dire un logiciel qui produit du texte, et qui dispose d’outils : lancer des commandes, lire et écrire des fichiers, appeler d’autres services. Il décide lui-même de ses étapes pendant qu’il travaille. Le principe du moindre privilège demande de donner à un programme seulement les droits nécessaires à sa tâche, mais il suppose de connaître cette tâche d’avance, ce qui est impossible ici. Surtout, le modèle distingue mal un ordre d’un simple texte lu : une phrase placée dans une page web ou un fichier peut le pousser à agir, avec les droits de la personne qui l’a lancé. Le danger apparaît quand trois conditions sont réunies : l’accès à des données précieuses, la lecture de contenus d’origine inconnue et un moyen d’envoyer des informations à l’extérieur. Il faut en retirer au moins une. Le texte propose ensuite de donner à l’agent un compte à lui, avec des autorisations de courte durée liées à une tâche, pour que chaque action lui soit attribuée. Les limites sont appliquées par le système d’exploitation, dans un environnement isolé et recréé à chaque tâche, sans réseau ni secret inutile. L’accord d’une personne est réservé aux actions impossibles à annuler, et porte sur l’effet exact. Enfin, les traces sont enregistrées par les systèmes touchés, pas par l’agent.

À lire aussi

  • Installer et utiliser Claude Code, l'agent de code d'AnthropicGuide pas-à-pas pour installer Claude Code, choisir un mode de permission, écrire un CLAUDE.md, verrouiller secrets, réseau et commandes dangereuses par règles, bac à sable et hooks, puis juger où l'agent sert vraiment.
  • Faire tourner un modèle chez soiFaire tourner un modèle de langage sur sa propre machine garantit une chose précise : le prompt ne part pas chez un fournisseur. Tout le reste (provenance des poids, outils qui appellent l'extérieur, journaux locaux, sécurité du poste, qualité des réponses) reste à la charge de celui qui a cru se débarrasser du problème.
  • Installer et utiliser Codex, l'agent de code d'OpenAIGuide pas à pas pour installer Codex CLI, s'authentifier sans exposer de jeton, régler le bac à sable et les approbations, écrire un fichier AGENTS.md, et savoir quand confier une tâche à l'agent ou s'en abstenir.
  • L'IA actuelle : assistants conversationnels et agentsÉtat des lieux en octobre 2026 des assistants d'IA générative (ChatGPT, Claude, Gemini, Copilot, Vibe, Meta AI, DeepSeek, Grok, modèles ouverts) et des agents qui agissent à leur place, avec ce que cela change pour la sécurité et la manière de les encadrer.

Pages voisines