Il était inoffensif à l'installation : prenez l'empreinte de vos skills d'agent

Il y a trois mois, vous avez installé un skill PDF. Il convertit toujours très bien les PDF — sauf que le répertoire contient désormais un fetch_helper.sh qu’il n’avait jamais eu, et que SKILL.md a gagné une ligne qui va chercher un script sur une adresse IP inconnue. La place de marché des skills l’a audité une fois, au moment de la publication. Depuis, ces fichiers vivent sur votre disque, où le dépôt amont, un script de mise à jour automatique ou un simple git pull distrait peut les réécrire. skill-integrity existe précisément pour cette fenêtre : il ne juge pas le contenu, il vous dit quels octets ont bougé.
« Je l’ai installé, donc c’est sûr » est une illusion
Un skill d’agent, c’est un dossier — un SKILL.md, quelques scripts et des ressources. Hermes les lit dans ~/.hermes/skills/ ; Claude Code lit ~/.claude/skills/. Aucune vérification de signature, aucun verrou de version. Les gens de la sécurité appellent cette classe d’attaque un rug-pull : inoffensif à l’installation, discrètement réécrit une fois qu’il a gagné votre confiance — un appel sortant ajouté, une URL de téléchargement échangée, un script qui lit votre environnement.
Deux propriétés de cette modification sont exactement ce que le hachage attrape : elle altère toujours les octets du fichier, et elle ne touche généralement qu’une poignée de fichiers.
Le plus petit service utile qu’il rend
skill-integrity calcule un SHA-256 pour chaque fichier de chaque répertoire de skill, enregistre le résultat sous forme de manifeste d’instantané, puis recalcule et compare à chaque vérification :
skills scanned: 23 (snapshot taken 2026-10-10T21:44:32+0800)
[~] pdf-extractor — MODIFIED
changed: SKILL.md
added: fetch_helper.sh
1 skill(s) changed since snapshot. Review diffs before trusting them.
Quelques détails utiles :
- Il parcourt
~/.hermes/skillset~/.claude/skillspar défaut, et note quels répertoires un instantané a couverts — leschecksuivants les réutilisent, de sorte qu’un écart de répertoires ne produit pas un mur de fausses entrées « removed ». - Les fichiers de plus de 512 Ko sont ignorés, tout comme
__pycache__,node_moduleset.git. Le nombre d’éléments ignorés, et lesquels pour chaque skill, est affiché, jamais caché. - Un répertoire de skill inaccessible est signalé comme un constat, jamais comme un scan vide et propre — un skill illisible est justement l’endroit où une modification se cacherait.
- Les codes de sortie ont un sens :
0propre,1constats,2pas encore d’instantané ou erreur d’usage.--no-fail-on-changeforce 0 tant que vous êtes encore en train de l’évaluer. - Le manifeste est en mode 0600, strictement local, sans aucun appel réseau.
Installer, puis prendre la référence
Il figure dans le catalogue curaté (skill-integrity, niveau communautaire, nécessite Hermes >= 0.21.6). Si le catalogue de votre build le liste, installez-le par son nom :
hermes plugins install skill-integrity
hermes plugins enable skill-integrity
Si votre catalogue n’a pas encore synchronisé cette entrée, installez depuis le dépôt comme le décrit son README :
git clone https://github.com/ZidoCode/skill-integrity ~/.hermes/plugins/skill-integrity
hermes plugins enable skill-integrity
Ensuite, faites la seule chose que tout le monde oublie — prenez une référence, sinon la vérification n’a rien à comparer et reste muette pour toujours :
/skill-integrity snapshot # enregistre la référence lue par le hook horaire
/skill-integrity check # diff fichier par fichier par rapport à l'instantané
/skill-integrity show # résumé de l'instantané
Vous pouvez aussi l’exécuter seul, sous forme d’un unique fichier sans dépendance (Python 3.8+) :
python3 skill_integrity.py snapshot
python3 skill_integrity.py check --json
Les deux chemins stockent leur état à des endroits différents : le plugin écrit ~/.hermes/plugin-data/skill-integrity/manifest.json, le CLI autonome utilise par défaut ~/.skill-integrity/manifest.json. Pointez le CLI vers l’état du plugin avec --state-dir :
python3 skill_integrity.py --state-dir ~/.hermes/plugin-data/skill-integrity check --json
Laissez l’agent surveiller ses propres skills
Le plugin enregistre un hook pre_llm_call qui s’exécute à peu près toutes les heures et n’injecte dans le contexte de l’agent que les noms des skills modifiés. Les exécutions propres ne disent rien, donc pas de bruit — et pas de faux sentiment de sécurité non plus.
Vous préférez un minuteur externe ? Une entrée cron fait très bien l’affaire :
0 */12 * * * python3 ~/skill-integrity/skill_integrity.py check --json >> ~/.skill-integrity/checks.log
Décidez où ce journal réside et qui peut le lire ; le guide sur les frontières de session est une bonne entrée en matière pour ce genre d’hygiène.
Les limites qu’il assume
Les outils de ce genre deviennent dangereux quand on les prend pour un certificat de sécurité : le README énonce donc les frontières — et elles valent la peine d’être répétées :
- Les hachages prouvent que des octets ont changé, pas une intention. Une mise à jour amont légitime et une réécriture malveillante sont indiscernables. Vous obtenez le déclencheur et la liste des fichiers ; lire le diff, c’est votre moitié du contrat.
- Il ne réécrit pas les instantanés historiques. Quelqu’un qui a le droit d’écriture peut prendre un nouvel instantané par-dessus ses propres traces — l’instantané est modifiable par l’agent, par conception.
- Du contenu malveillant dans un fichier inchangé ? Hors périmètre. C’est le travail de l’analyse de contenu.
- C’est un outil d’intégrité d’inventaire, pas un antivirus. Les fichiers de plus de 512 Ko et les liens symboliques sont des angles morts — comptés, mais non suivis.
Traitez-le donc comme un rappel de contrôle, pas comme un détecteur de métaux.
Une routine qui tient vraiment
- Prenez l’instantané juste après l’installation des skills. Une référence prise une semaine plus tard est la référence des modifications de quelqu’un d’autre.
- Vérifiez après chaque mise à jour de skill ou pull amont, lisez le diff, puis reprenez un instantané.
- Quand un constat tombe, suivez cet ordre : lisez le diff et confirmez que vous ne l’avez pas écrit ; demandez-vous à quoi le skill peut accéder (fichiers ? réseau ? variables d’environnement ?) ; en cas de doute, désactivez-le et déplacez le répertoire ailleurs ; s’il a pu lire des identifiants, faites tourner ces clés avec le playbook d’hygiène des identifiants.
- Dans les configurations multi-profils, le plugin déduit les répertoires de skills et d’état via
get_hermes_home(), donc les profils non standards sont couverts — mais chaque profil garde son propre instantané.
Pour l’écosystème au sens large, commencez par le fonctionnement du catalogue de plugins et la référence hermes plugins. Le même auteur livre aussi un janitor de processus et un registre de sécurité ; l’idée commune est de rendre des comptes sur ce qu’un agent laisse derrière lui.