Policies: Model-Based Authorization
Attach policies to Eloquent models and use them in controllers.
Policies: Model-Based Authorization is a free PHP Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the PHP Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What is a Policy?
A Policy is a class that organises authorization logic for a specific Eloquent model. Policies are recommended when you have multiple authorization actions for the same model.
Generating a Policy
Use Artisan to generate a policy. Add --model to pre-fill standard methods.
$ php artisan make:policy PostPolicy --model=PostPolicy Methods
Each method corresponds to an action. It receives the authenticated user and the model instance.
<?php
class PostPolicy
{
public function view(?User $user, Post $post): bool
{
return $post->is_published || $user?->id === $post->user_id;
}
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
public function delete(User $user, Post $post): bool
{
return $user->id === $post->user_id || $user->isAdmin();
}
}Registering Policies
In Laravel 11+, policies are auto-discovered if they follow naming conventions (Post model → PostPolicy). You can also register manually in AuthServiceProvider.
Using Policies in Controllers
Call $this->authorize("action", $model) — Laravel finds the matching policy automatically.
<?php
public function update(Request $request, Post $post): RedirectResponse
{
$this->authorize("update", $post);
$post->update($request->validated());
return redirect()->route("posts.show", $post);
}Policy in Blade
The @can directive works with policies the same way as with gates.
@can('update', $post)
<a href="/posts/{{ $post->id }}/edit">Edit</a>
@endcanbefore() Method
The optional before() method on a policy runs before other methods. Return true to grant blanket access (e.g. for admins).
<?php
public function before(User $user, string $ability): ?bool
{
if ($user->isAdmin()) return true;
return null; // continue to specific method
}Create Action (no model instance)
The create policy method receives only the user (no model) since no instance exists yet.
<?php
public function create(User $user): bool
{
return $user->hasVerifiedEmail();
}Checking Policies Manually
Use the Gate facade or the user model to check policies directly.
<?php
Gate::allows("update", $post); // true/false
$user->can("update", $post); // true/false
$user->cannot("delete", $post); // true/falsePolicy Responses
Return a Response object from a policy method to customise the denial message.
<?php
use Illuminate\Auth\Access\Response;
public function publish(User $user, Post $post): Response
{
return $user->isEditor()
? Response::allow()
: Response::deny("Only editors can publish posts.");
}Testing Policies
Test policies by acting as a specific user in PHPUnit.
<?php
public function test_owner_can_delete_post(): void
{
$user = User::factory()->create();
$post = Post::factory()->create(["user_id" => $user->id]);
$this->assertTrue($user->can("delete", $post));
}Summary
Policies group model-level authorization. Generate with make:policy --model. Use $this->authorize() in controllers and @can in Blade. Use before() for admin bypass.
Quick Check
Which policy method receives only the user without a model instance?
Frequently asked questions
Is the “Policies: Model-Based Authorization” lesson free?
Yes — the full text of “Policies: Model-Based Authorization” is free to read here on the web, and the PHP Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the PHP Academy course, upgrade to CoddyKit PRO.
What will I learn in “Policies: Model-Based Authorization”?
Attach policies to Eloquent models and use them in controllers. You practise PHP Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start PHP Academy?
No prior experience is required. PHP Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Policies: Model-Based Authorization” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this PHP Academy lesson?
Yes. Every PHP Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Authentication with Laravel Breeze
- Protecting Routes with Middleware
- Gates: Simple Authorization Checks
- Policies: Model-Based Authorization