Demandeur, attribut, sujet : les mots de ce composant

À lire avant tout le reste au sujet du composant : un mot y signifie l’inverse de ce que la littérature de sécurité vous fait attendre, et le choix est délibéré.

Toute question posée à Access Control est une AccessRequest, et elle porte quatre choses.

new AccessRequest(
    requester: $token,          // qui demande
    attribute: 'EDIT',          // ce qu'il veut faire
    subject: $post,             // ce sur quoi il veut le faire
    environment: new AccessEnvironment(['ip' => $ip]),  // les circonstances
);

Ces quatre champs répondent aux catégories d’attributs d’ABAC et de XACML, mais deux des noms diffèrent. Ce que XACML appelle le subject est ici le requester, et ce qu’il appelle l’action est l’attribute. La resource est le subject, et l’environnement garde son nom.

Pourquoi subject désigne la ressource

Le sujet est la chose sur laquelle on agit, pas l’acteur. C’est ce qu’il veut dire dans Symfony depuis dix ans : c’est le mot qu’emploie tout votant applicatif, le mot d’#[IsGranted], le mot de la fonction Twig, et le mot d’AuthorizationCheckerInterface::isGranted(), que la passerelle Security de ce composant implémente.

Le renommer ne supprimerait pas la traduction, cela la déplacerait à cette jointure, là où tout votant existant et tout gabarit existant la rencontreraient. Donc subject reste, et l’acteur reçoit un nom bien à lui : requester, qui dit plus clairement que subject ne l’a jamais fait qui pose la question.

Si vous venez de XACML, c’est le seul endroit où vous ayez une substitution à faire. Si vous venez de Symfony, il n’y a rien à substituer.

Le demandeur n’est pas un utilisateur

Il n’y a aucune UserInterface nulle part dans le contrat, ni de jeton non plus. Le demandeur est mixed, et il est ce que votre application dit qu’il est :

  • un TokenInterface de Symfony, quand vous en avez un,
  • un objet qui implémente UserWithRoleInterface, ou qui porte simplement une méthode getRoles(),
  • un acteur machine, un compte de service, une clé d’API,
  • une chaîne.

Un votant qui ne comprend pas un demandeur s’abstient. Rien ne lève, rien ne refuse par accident.

L’attribut n’est pas seulement une chaîne

EDIT, ROLE_ADMIN et IS_AUTHENTICATED_FULLY sont les formes familières, et ce sont des chaînes qu’un votant reconnaît. L’attribut a aussi le droit d’être une Expression ou une Closure, traitées chacune par un votant dédié. Rien dans le contrat n’impose une chaîne, donc un objet valeur de votre cru fonctionne aussi, pourvu qu’un de vos votants le comprenne.

L’environnement, ce sont les circonstances

AccessEnvironment contient ce qui n’appartient ni au demandeur, ni au sujet, ni à l’attribut : une adresse IP, une heure de la journée, un pays, la requête HTTP elle-même. Chaque point d’entrée remplit ce qu’il connaît, et une application est libre d’ajouter ses propres clés.

Il mérite un article à lui seul, et il l’aura. Pour l’instant, la moitié utile de la phrase est que ces quatre champs font toute la question : qui, quoi, sur quoi, et dans quelles circonstances.

La page de vocabulaire de la documentation en est la version de référence, et c’est la page à lire en premier si un mot employé ici veut déjà dire autre chose pour vous. C’est probablement le cas.