3.7 KiB
context-hub — Filtrage per-agent du contenu d'un scope
Date : 2026-08-16 Repo : bolbol/context-hub (app/models.py, app/routes/api.py, app/routes/mcp.py)
Probleme
Le scope infra de context-hub est servi en tout-ou-rien : has_scope_access(agent, scope)
controle l'acces au scope entier, mais aucun filtrage n'existait a l'interieur du contenu.
Consequence concrete : Gemini (scope infra autorise) recevait les memes cles que Claude, y
compris des pieges strictement lies a mcp-nas (heredoc timeout, session-poison-apres-3-erreurs)
-- un outil exclusif a Claude, inutilisable et non pertinent pour Gemini. Pas dangereux (pas de
fuite entre spheres tt/perso/nyora), juste du bruit qui dilue le contexte de l'agent consommateur.
Identifie le 02/07/2026, laisse en l'etat car non urgent a l'epoque.
Trouve en meme temps : deux cles infra contradictoires sur le meme sujet -- mcp_nas (a jour,
dit le piege heredoc resolu depuis le 30/07) et mcp_nas_heredoc_piege_confirme (perimee, dit le
piege toujours actif, confirmee le 02/07 avant le fix). La deuxieme n'avait jamais ete purgee.
Fix
Ajout d'une metadonnee optionnelle _agent_only dans le JSON stocke par scope :
{"_agent_only": {"nom_de_cle": ["CLAUDE", "HERMES_NABIL"]}}. Une nouvelle fonction sync
filter_content_for_agent(content, agent_name) dans app/models.py retire du contenu renvoye
toute cle listee dans _agent_only si l'agent appelant n'est pas dans la liste autorisee, et
retire systematiquement la cle _agent_only elle-meme de la reponse (metadonnee interne, jamais
exposee). Le contenu stocke en base n'est jamais modifie -- uniquement la copie renvoyee.
Appliquee aux 7 points de sortie qui servaient un scope sans filtrage : GET /api/rules/{scope},
GET /api/search, GET /api/context (api.py) + tools MCP get_rules, search_rules,
get_agent_config, get_my_context (mcp.py). Aucun changement de schema DB, aucune migration --
compatible avec tout contenu existant qui n'a pas de cle _agent_only.
Contenu infra mis a jour : cle mcp_nas_heredoc_piege_confirme supprimee (perimee), cle
mcp_nas marquee _agent_only: [CLAUDE, HERMES_NABIL], cle last_claude_session egalement
(bookkeeping Claude, sans interet pour les autres agents), valeur rafraichie a 2026-08-16.
Verification
Redemarrage via Portainer API (bind mount ./app:/app/app, pas de rebuild necessaire ; docker
absent du shell mcp-nas, restart fait via POST /api/endpoints/2/docker/containers/{id}/restart
avec JWT bestof). Healthcheck repasse healthy apres restart. Teste en clair sur GET /api/rules/infra
et GET /api/context avec la cle CLAUDE (mcp_nas + last_claude_session presents) et la cle GEMINI
(absents, _agent_only absent des deux).
Transport MCP Streamable HTTP (POST /mcp/, stateless, json_response=True) verifie separement en
JSON-RPC brut (tools/call), les 4 tools concernes testes cle CLAUDE + cle GEMINI : get_rules,
search_rules, get_agent_config, get_my_context -- meme resultat que le REST (filtrage actif
cote GEMINI, intact cote CLAUDE). get_agent_config/get_my_context exigent un champ name/agent
dans les arguments par schema JSON, mais l'autorisation reelle utilise current_agent_var (identite
de connexion X-API-Key), jamais ce champ declaratif -- ne pas s'y fier pour usurper un agent.
Extension future
Pour marquer une nouvelle cle comme reservee : ajouter son nom dans _agent_only du scope concerne
avec la liste des agent_name autorises (valeurs exactes de la table agents, pas les identites
Gitea/SSH/Portainer -- ex. HERMES_NABIL, pas NABIL). Fonctionne sur les 5 scopes historiques
(infra/llm/nyora/perso/tt) ; n'affecte pas le scope coding (memory_entries, mecanisme separe).