---
title: "Gate, Blade & policies — Teams for Laravel | Roundly"
description: "Authorize with $user->can('teams.<permission>', $team), @teamPermission / @teamRole / @teamOwner, and scaffolded team policies."
url: https://roundly-consulting.com/open-source/docs/teams-for-laravel/authorization
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Teams for Laravel](https://roundly-consulting.com/open-source/docs/teams-for-laravel.md)

# Gate, Blade & policies

With gate.register on (the default), authorize the idiomatic Laravel way. The ability is <prefix>.<permission> and the team is the gate argument:

```php
if ($user->can('teams.manage-billing', $team)) {
    // ...
}

$user->can('teams.posts.publish', $team);     // a permission ability
$user->can('teams.owner', $team);              // the owner ability
Gate::authorize('teams.team.update', $team);   // throws a 403 when denied
```

## How the gate resolves

- The package registers a Gate::before hook, not named abilities. It only answers abilities under the prefix (teams. by default) whose first argument is a Team.
- teams.owner resolves to $team->isOwnedBy($user); any other teams.<permission> resolves to memberHasPermission().
- A miss returns null, not false, so your own gates and policies still decide — the hook never blocks unrelated abilities.
- Rename with gate.prefix and gate.owner\_ability, or set TEAMS\_REGISTER\_GATE=false to register neither the hook nor the Blade directives.

## Blade directives

```blade
@teamPermission($team, 'manage-billing')
    <a href="/billing">Billing</a>
@endteamPermission

@teamRole($team, 'admin')
    <button>Manage team</button>
@endteamRole

@teamOwner($team)
    <button>Delete team</button>
@endteamOwner

{{-- Check a specific member instead of the signed-in user --}}
@teamPermission($team, 'posts.publish', $otherUser)
    <span>Can publish</span>
@endteamPermission
```

Each directive checks the signed-in user by default; pass a member as the last argument to check someone else. @teamRole and @teamPermission both fail for an expired membership.

## Team policies

teams:policy scaffolds a policy extending AbstractTeamPolicy, whose before() grants every ability on a team to its owner and otherwise defers to your methods. Class-level abilities — $user->can('create', Team::class), viewAny — carry no team, so before() lets them through to your policy method:

```bash
php artisan teams:policy TeamPolicy           # writes app/Policies/TeamPolicy.php
php artisan teams:policy TeamPolicy --force   # overwrite an existing file
```

```php
namespace App\Policies;

use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Teams\Models\Team;
use RoundlyConsulting\Teams\Policies\AbstractTeamPolicy;

class TeamPolicy extends AbstractTeamPolicy
{
    public function view(Model $user, Team $team): bool
    {
        return $this->allows($user, $team, 'team.view');
    }

    public function update(Model $user, Team $team): bool
    {
        return $this->allows($user, $team, 'team.update');
    }

    public function delete(Model $user, Team $team): bool
    {
        return $this->allows($user, $team, 'team.delete');
    }
}
```

Register it the usual way (policy auto-discovery or Gate::policy()). For hand-written policies, the HasTeamPolicies trait supplies the same owns() and allows() helpers:

```php
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Teams\Concerns\HasTeamPolicies;
use RoundlyConsulting\Teams\Models\Team;

class PostPolicy
{
    use HasTeamPolicies;

    public function update(Model $user, Team $team): bool
    {
        return $this->owns($user, $team) || $this->allows($user, $team, 'posts.update');
    }
}
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/teams-for-laravel.md)
