Ce document explique comment restreindre l'accès à certains agents en fonction des rôles Symfony ou des identifiants utilisateur.
Chaque agent (SynapseAgent) peut avoir un contrôle d'accès configuré via le champ accessControl :
[
'roles' => ['ROLE_TEACHER', 'ROLE_ADMIN'], // Rôles Symfony autorisés
'userIdentifiers' => ['jean.dupont@example.com'] // Identifiants utilisateur autorisés
]
| Configuration | Comportement |
|---|---|
accessControl = null |
Agent public : accessible à tous les utilisateurs |
accessControl = ['roles' => [], 'userIdentifiers' => []] |
Agent verrouillé : accessible à personne |
accessControl configuré |
Agent restreint : accessible si l'utilisateur a au moins un rôle OU son identifiant est dans la liste |
$agent = new SynapseAgent();
$agent->setKey('assistant_enseignant');
$agent->setName('Assistant Enseignant');
$agent->setAccessControl([
'roles' => ['ROLE_TEACHER', 'ROLE_ADMIN'],
'userIdentifiers' => []
]);
Résultat :
ROLE_TEACHER → Accès autoriséROLE_ADMIN → Accès autoriséROLE_STUDENT → Accès refusé$agent->setAccessControl([
'roles' => [],
'userIdentifiers' => ['testeur1@example.com', 'testeur2@example.com']
]);
Résultat :
testeur1@example.com → Accès autorisétesteur2@example.com → Accès autoriséROLE_ADMIN) → Accès refusé$agent->setAccessControl([
'roles' => ['ROLE_RH'],
'userIdentifiers' => ['directeur@example.com']
]);
Résultat :
ROLE_RH → Accès autorisédirecteur@example.com (même sans ROLE_RH) → Accès autorisé/synapse/admin/intelligence/agentsExemple de saisie :
Rôles autorisés :
ROLE_TEACHER
ROLE_ADMIN
Utilisateurs autorisés :
jean.dupont@lycee.fr
marie.martin@lycee.fr
L'identifiant utilisateur est fourni par la méthode getIdentifier() de votre entité User (qui implémente ConversationOwnerInterface).
Exemples selon votre application :
class User implements ConversationOwnerInterface
{
public function getIdentifier(): string
{
return $this->email; // jean.dupont@example.com
}
}
class User implements ConversationOwnerInterface
{
public function getIdentifier(): string
{
return $this->username; // jdupont
}
}
class User implements ConversationOwnerInterface
{
public function getIdentifier(): string
{
return $this->publicId; // USER-12345
}
}
Synapse filtre automatiquement les agents via AgentRegistry :
// Récupérer tous les agents accessibles par l'utilisateur connecté
$agents = $agentRegistry->getAll();
// → Seuls les agents autorisés sont retournés
// Récupérer un agent spécifique (avec vérification de permission)
$agent = $agentRegistry->get('assistant_rh');
// → Retourne null si l'agent n'existe pas OU si l'utilisateur n'a pas les permissions
$chatService->ask('Question', ['agent' => 'assistant_rh']);
// → Si l'utilisateur n'a pas accès, l'agent est ignoré silencieusement
// → Le système utilise le prompt par défaut
Comportement : Pas d'erreur levée, l'UX reste fluide.
Vous pouvez implémenter votre propre logique de permission en étendant PermissionCheckerInterface :
namespace App\Security;
use ArnaudMoncondhuy\SynapseCore\Contract\PermissionCheckerInterface;
use ArnaudMoncondhuy\SynapseCore\Storage\Entity\SynapseAgent;
class CustomAgentPermissionChecker implements PermissionCheckerInterface
{
public function canUseAgent(SynapseAgent $agent): bool
{
// Votre logique custom
// Ex : vérifier un système d'ACL, interroger une API externe, etc.
return true;
}
// ... autres méthodes de PermissionCheckerInterface
}
Puis configurez dans services.yaml :
services:
ArnaudMoncondhuy\SynapseCore\Contract\PermissionCheckerInterface:
class: App\Security\CustomAgentPermissionChecker
| Aspect | Détail |
|---|---|
| Configuration | Via UI Admin (/synapse/admin) ou programmatiquement |
| Stockage | Champ JSON access_control dans la table synapse_agent |
| Vérification | Automatique dans AgentRegistry::get() et ::getAll() |
| Logique | Rôles OU identifiants (union, pas intersection) |
| Défaut | null = agent public |
| Extensible | Oui, via implémentation custom de PermissionCheckerInterface |
How can I help you explore Laravel packages today?