Requester, attribute, subject: the words this component uses

Read this before anything else about the component: one word in it means the opposite of what the security literature makes you expect, and the choice is deliberate.

Every question put to Access Control is an AccessRequest, and it carries four things.

new AccessRequest(
    requester: $token,          // who asks
    attribute: 'EDIT',          // what they want to do
    subject: $post,             // what they want to do it to
    environment: new AccessEnvironment(['ip' => $ip]),  // the circumstances
);

They line up with the attribute categories of ABAC and XACML, but two of the names differ. What XACML calls the subject is the requester here, and what it calls the action is the attribute. The resource is the subject, and the environment keeps its name.

Why subject means the resource

The subject is the thing being acted upon, not the actor. That is what it has meant in Symfony for a decade: it is the word every application voter uses, the word of #[IsGranted], the word of the Twig function, and the word of AuthorizationCheckerInterface::isGranted(), which this component’s Security bridge implements.

Renaming it would not remove the translation, it would move it to that seam, where every existing voter and every existing template would meet it. So subject stays, and the actor gets a name of its own: requester, which says more plainly than subject ever could who is doing the asking.

If you come from XACML, this is the only place you have to make the substitution. If you come from Symfony, there is nothing to substitute.

The requester is not a user

There is no UserInterface anywhere in the contract, and no token either. The requester is mixed, and it is whatever your application says it is:

  • a Symfony TokenInterface, when you have one,
  • an object implementing UserWithRoleInterface, or simply carrying a getRoles() method,
  • a machine actor, a service account, an API key,
  • a string.

A voter that does not understand a requester abstains. Nothing raises, nothing denies by accident.

The attribute is not only a string

EDIT, ROLE_ADMIN and IS_AUTHENTICATED_FULLY are the familiar shapes, and they are strings a voter recognises. The attribute is also allowed to be an Expression or a Closure, each answered by a voter of its own. Nothing in the contract says it must be a string, so a value object of your own works too, provided a voter of yours understands it.

The environment is the circumstances

AccessEnvironment holds what belongs neither to the requester, nor to the subject, nor to the attribute: an IP address, an hour of the day, a country, the HTTP request itself. Each entry point fills in what it knows, and an application is free to add its own keys.

It deserves an article of its own, and it will get one. For now, the useful half of the sentence is that the four fields are the whole question: who, what, to what, and under which circumstances.

The vocabulary page of the documentation is the reference version of this, and it is the page to read first if a word here already means something else to you. It probably does.