0Pricing
PHP Academy · Lesson

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=Post

Policy 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>
@endcan

before() 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/false

Policy 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

  1. Authentication with Laravel Breeze
  2. Protecting Routes with Middleware
  3. Gates: Simple Authorization Checks
  4. Policies: Model-Based Authorization
← Back to PHP Academy