Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Aridez's avatar

How do you handle a resource being managed differently depending on a user role while using policies?

I find myself in a situation where I have two roles, "Admin" and a "Organizer". The "Admin" accesses the AdminUserController to update users, while the "Organizer" accesses the UserController to do so. This is important since the user indexing and input validation is different in both cases: the organizer only indexes a subset of users and can update a subset of fields.

For the controller I am using resource controllers ( https://laravel.com/docs/9.x/controllers#resource-controllers ) and they are the ones managing the input validation, including the different filtering on the index method as well as the input validation.

To authorize actions I am using policies, and with them being a resource-based authorization method, I can only define a single policy to authorize the access / update to the Users table. The problem is that this authorization is different depending on the controller called. I like to encapsulate the Auth logic within policies, but I am not sure what would be a "clean" way to solve this in this case. The only options that came to mind are:

  1. Pass the controller called to the policy: That would make for a controlled-based authorization and not a resource-based authorization and the mix doesn't feel right.

  2. Make a single controller and share authorization logic in it: This would allow to make the correct input validation / filtering depending on the role, but that would be mixing concerns too.

  3. Use a gate in the controller: In this case the authorization logic would stop being encapsulated in the policy methods. Right now I have gates implemented to check for permissions, but the use of these gates is reserved for policies and using them outside doesn't feel right either.

Seems like making two policies would be a possible solution, but that is not an allowed practice in Laravel, so instead of going through a major refactor or mixing authorization philosophies, I am looking for a clean "laravel-way" to solve this issue.

Have any of you face a situation like this in the past? How did you solve it in a clean way?

0 likes
1 reply
Aridez's avatar

Some thoughts on this. I was thinking that maybe the way to go could be to pass an array of permissions needed from the controller to the policy.

The UserController update would look like:

 $this->authorize('update', [$user, Role::findByName('Organizer')->permissions]);

The AdminController update would look like:

 $this->authorize('update', [$user, Role::findByName('Admin')->permissions]);

And then on the UserPolicy update method, pass this additional parameter and check that all permissions are met:

    public function update(User $user, User $model, Collection $permissions)
{
    foreach ($permissions as $permission) {
        $this->authorize($permission->name);
    }

    //additional logic
}

Since this is something that would be used platform-wide it would be nice to maybe extend the base policy class to always check if there are permissions and validate them beforehand, but I'm not sure how it could be done. I think that passing this array can do for a decent solution for now though 🤔.

Please or to participate in this conversation.