> ## Content Index
> Fetch the complete content index at: https://securinglaravel.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Security Tip: Don't Forget About Policy Filters!
- URL: https://securinglaravel.com/security-tip-policy-filters/
- Published: 2021-09-21T16:08:54.000Z
- Updated: 2024-09-17T14:09:03.000Z
- Description: [Tip#2] Policy Filters let you implement shared authorisation checks across your entire policy without repeating code in every method.
- Author: Stephen Rees-Carter
- Tags: Security Tips, Policies, Authorisation

Laravel includes an authorization feature known as *Policies*, which allow you to wrap up authorization rules relating to a specific model within a class. You can find all the details in the [Laravel documentation](https://laravel.com/docs/authorization?ref=securinglaravel.com#creating-policies), but in a nutshell, you have these main methods within the policy, which reflect the different abilities a user can perform on a model:

```
viewAny(User $user)
view(User $user, Tip $tip)
create(User $user)
update(User $user, Tip $tip)
delete(User $user, Tip $tip)
restore(User $user, Tip $tip)
forceDelete(User $user, Tip $tip)
```

As a reference, here is a blank policy object: [https://gist.github.com/valorin/f51de37759eeac84eb75433d7bbcd25c](https://gist.github.com/valorin/f51de37759eeac84eb75433d7bbcd25c?ref=securinglaravel.com).

Policy objects on their own are great, and give you a lot of flexibility when setting up authorisation rules within your apps. However, consider the scenario where you have admin users who are allowed every ability. You will find yourself repeating this multi-conditional pattern in every policy method:

```
public function view(User $user, Tip $tip)
{
    return $user->admin || $tip->user_id === $user->id;
}
```

While this does work, it’s ugly and relies on you including the admin conditional in every single method. If that behaviour changes (maybe you switch from an admin flag to user level), you’re stuck updating every single instance of the conditional in a class… which isn’t fun. Or maybe you need to add another check - a moderator has admin powers for this specific model. Now you’ve got **three** conditionals replicated in every ability method… 😔

**The solution is to use a Policy Filter!**

A [Policy Filter](https://laravel.com/docs/authorization?ref=securinglaravel.com#policy-filters) is a `before()` method that runs before the ability specific methods run. It allows you to define your policy-wide rules once, removing the code duplication.

```
public function before(User $user, $ability)
{
    if ($user->isAdmin() || $user->isTipModerator()) {
        return true;
    }
}
```

The `before()` method has three return states:

- `true` \- Grant access to the user, skipping the ability specific method.
- `false` \- Block access to the user, skipping the ability specific method.
- `null/void` \- Run the ability specific method to check access.

With these states, you can easily use this feature to do things like allowing admin users or blocking suspended users, without making a mess of your ability-specific logic. You could also wrap the `before()` method into a trait to reuse between policies.

To see it in action: [https://gist.github.com/valorin/c7830b9e300db3ef977c11657659ac7b](https://gist.github.com/valorin/c7830b9e300db3ef977c11657659ac7b?ref=securinglaravel.com)

---

**Found this security tip helpful?* Don't forget to* [*subscribe*](https://securinglaravel.com/#/portal/signup) *to receive new* [*Security Tips*](https://securinglaravel.com/tag/tips/) *each week, and upgrade to a* [*premium subscription*](https://securinglaravel.com/#/portal/signup) *to receive monthly* [*In Depth articles*](https://securinglaravel.com/tag/in-depth/)*, or toss a coin in the* [*tip jar*](https://securinglaravel.com/#/portal/support)*.*

*You can follow Stephen on* [*Twitter*](https://twitter.com/valorin?ref=securinglaravel.com)*,* [*Fediverse*](https://phpc.social/@valorin?ref=securinglaravel.com)*,* [*LinkedIn*](https://www.linkedin.com/in/stephen-rees-carter/?ref=securinglaravel.com)*,* [*Pinkary*](https://pinkary.com/@valorin?ref=securinglaravel.com)*,* [*Bluesky*](https://bsky.app/profile/valorin.bsky.social?ref=securinglaravel.com)*, and* [*Threads*](https://www.threads.net/@valorinsrc?ref=securinglaravel.com)*, and reach out if you're looking for a* [*Laravel Security Audit and Penetration Test*](https://stephenreescarter.net/laravel-security-audits-and-pentesting/?utm%5Fsource=securinglaravel.com) *or a budget-friendly* [*Security Review*](https://stephenreescarter.net/laravel-security-reviews/?utm%5Fsource=securinglaravel.com)*.*

*Finally, to learn more about security through a series of interactive challenges, check out Stephen's new course:* [*Practical Laravel Security*](https://practicallaravelsecurity.com/?utm%5Fsource=securinglaravel.com)*.*