Pourquoi un rôle censé permettre uniquement de proposer des changements au menu du jour peut-il aussi modifier la page des mentions légales du restaurant ? C’est la question posée par le gérant après avoir constaté qu’un serveur, chargé de mettre à jour les plats du jour via un accès WordPress, avait accidentellement publié une modification sur la page de réservation — un rôle personnalisé, créé rapidement à partir du rôle « éditeur » par simple copie, avait hérité de bien plus de capacités que prévu.
Cet article ne traite pas de la création de rôles personnalisés dans son ensemble, déjà documentée par ailleurs : il se concentre sur le diagnostic et la correction d’un rôle existant devenu trop permissif avec le temps.
Comment le rôle avait été créé
Le rôle « menu-jour » avait été défini par duplication du rôle editor natif, avec l’intention de retirer ensuite les capacités superflues. Cette dernière étape avait été oubliée, ou seulement partiellement effectuée : le rôle conservait la capacité edit_others_pages, permettant de modifier n’importe quelle page du site, y compris celles sans rapport avec le menu du jour.
Ce que l’audit a révélé

Un script exécuté depuis le shell WP-CLI a permis de lister exactement les capacités attribuées au rôle :
wp eval '
$role = get_role("menu_jour");
print_r($role->capabilities);
'
Trente-quatre capacités apparaissaient, dont plusieurs sans lien avec la mission réelle du rôle : edit_others_pages, edit_others_posts, delete_pages, manage_categories, edit_theme_options, moderate_comments. Aucune de ces capacités n’était nécessaire pour proposer une modification du menu du jour publié en tant que type de contenu personnalisé.
Reconstruire le rôle capacité par capacité
Plutôt que de partir d’un rôle existant et de retirer des droits un par un, le choix a été fait de recréer entièrement le rôle en n’ajoutant que les capacités strictement nécessaires :
remove_role('menu_jour');
add_role('menu_jour', 'Gestion du menu du jour', array(
'read' => true,
'edit_menu_jour' => true,
'edit_published_menu_jour' => true,
'upload_files' => true,
));
Le type de contenu personnalisé menu_jour a été enregistré avec ses propres capacités dédiées, plutôt que de réutiliser celles des articles ou des pages :
register_post_type('menu_jour', array(
'capability_type' => 'menu_jour',
'map_meta_cap' => true,
'capabilities' => array(
'edit_post' => 'edit_menu_jour',
'edit_posts' => 'edit_menu_jour',
'publish_posts' => 'publish_menu_jour',
),
));
Le paramètre map_meta_cap confie à WordPress la résolution fine des vérifications de capacité, plutôt que de s’appuyer sur des capacités génériques et partagées avec le reste du contenu du site.
Un contrôle de validation ajouté en complément
Pour éviter qu’une modification du menu ne se publie instantanément sans relecture, un statut « en attente » a été imposé au rôle via la capacité publish_menu_jour, réservée au gérant. Le serveur propose une modification, mais seule une personne disposant du rôle editor ou administrator peut la faire passer en publication.
Vérifier les autres rôles du site
Cet incident a poussé l’équipe à passer en revue l’ensemble des rôles personnalisés du site avec la même méthode : lister les capacités réellement utilisées par chaque fonctionnalité métier, puis comparer avec les capacités effectivement attribuées. Deux autres rôles, créés pour la gestion des réservations et des avis clients, présentaient le même écart entre l’intention initiale et les droits réellement accordés.
Documenter les rôles pour éviter la récidive
Au-delà de la correction ponctuelle, l’équipe a mis en place une fiche de référence pour chaque rôle personnalisé du site, listant sa raison d’être, les capacités qui lui sont attribuées et la personne ou le service métier qui l’utilise au quotidien. Cette fiche est relue à chaque ajout de fonctionnalité touchant aux permissions, avant toute modification du code des rôles, plutôt qu’après coup lors d’un audit.
Cette documentation a également permis de repérer qu’un rôle créé temporairement, pour un remplacement de personnel pendant les congés d’été, n’avait jamais été supprimé une fois la période terminée. Un compte disposant encore de ce rôle, associé à une personne qui n’intervenait plus sur le site depuis plusieurs mois, a ainsi pu être identifié et désactivé, en complément direct du travail de reconstruction des capacités du rôle « menu-jour ».
En résumé
Dupliquer un rôle existant pour aller vite est une tentation compréhensible, mais elle transporte silencieusement toutes les capacités du rôle d’origine. Repartir d’une liste vide et n’ajouter que ce qui est strictement nécessaire, en s’appuyant sur map_meta_cap et des capacités dédiées au type de contenu, évite ce genre de dérive découverte trop tard.