Using scopes on a user to determine access - Policy or Firewall?

Did any one here work with the idea of “scopes” in terms of Flow and security?

Most likely API based (not limited to), a client requesting GET ^/api/registrations must have the read_registration scope on the authenticated user.

This is not related to Roles, making me wonder how this would look in terms of Policy.yaml configuration. It’s not a specific permission to a role, so the normal privilegeTargets configuration can’t seem to fit

privilegeTargets:
  'Vendor\RestApi\Security\Authorization\Privilege\ApiPrivilege':
    'read_registrations':
      matcher: 'path("^/api/registrations") && method("GET")'
    'create_registrations':
      matcher: 'path("^/api/registrations") && method("POST")'

The idea here, was to use the key (ex. read_registrations) as the required scope and the matcher being the definition of the request path and method.

While writing this, I came to think of the firewall that have CSRF protection as a default registration. Could this be a place to implement this?

  • It’s out far, even before the Policy kicks in
  • We have the security context - so we know if you are authenticated and who you are

And at that point, do scope tests like (pseudo-code)

yaml configuration under correct namespace

          'Vendor.Api:ScopeProtection':
            pattern: 'Vendor\RestApi\Security\RequestPattern\ScopeProtection'
            interceptor: ValidScopeMissing

ScopeProtection class

$relevantScope = $this->findRelevantScopeByHttpRequest($request->getHttpRequest());
$account = $this->securityContext->getAccount();
$user = $this->userRepository->findByAccount($account);

if ($user->hasScope($relevantScope)) {
...
}

and end up throwing AccessDeniedException in the ValidScopeMissing similar to

Please bring any knowledge or feedback to the idea to help me and anyone else looking into similar topics :partying_face: