---
url: /reference/authorization.md
description: >-
  How MediaItemPolicy and MediaFolderPolicy decide access, how to replace them,
  and examples for staff-only and per-team rules.
---

# Authorization

The library asks Laravel's Gate for every action. Two policies ship with the package and are registered for your configured item and folder models, unless you already registered your own.

## Default abilities

`MediaItemPolicy` (`Hoceineel\FilamentMediaLibrary\Policies\MediaItemPolicy`):

| Ability | Default |
|---|---|
| `viewAny` | Allowed for any signed-in user. |
| `view` | Allowed for the uploader, for any non-private file, and for users who pass `viewPrivate`. |
| `create` | Allowed for any signed-in user. |
| `update` | Same as `view`. |
| `delete` | Same as `view`. |
| `restore` | Same as `view`. |
| `forceDelete` | Same as `view`. |
| `viewPrivate` | Denied for everyone. Grant it to let staff see other people's private files. |

`MediaFolderPolicy` has `viewAny`, `view`, `create`, `update` and `delete`. `view` follows the same rule as items: public folders are open, private folders belong to their creator, and `viewPrivate` on the item model opens them to staff. `update` and `delete` follow `view`. It has no `restore` or `forceDelete`.

In short, shared media is open to every panel user and private media belongs to its uploader. If that is too open for you, replace the policy.

## Use your own policy

Extend the shipped policy and override what you need, then register it with the Gate:

```php
namespace App\Policies;

use Hoceineel\FilamentMediaLibrary\Models\MediaItem;
use Hoceineel\FilamentMediaLibrary\Policies\MediaItemPolicy as BasePolicy;
use Illuminate\Contracts\Auth\Authenticatable;

class MediaItemPolicy extends BasePolicy
{
    public function delete(Authenticatable $user, MediaItem $item): bool
    {
        return $user->isEditor() && parent::delete($user, $item);
    }

    public function viewPrivate(Authenticatable $user): bool
    {
        return $user->isAdmin();
    }
}
```

```php
// AppServiceProvider::boot()
use Hoceineel\FilamentMediaLibrary\Models\MediaItem;
use Illuminate\Support\Facades\Gate;

Gate::policy(MediaItem::class, \App\Policies\MediaItemPolicy::class);
```

The package only registers its policy when none exists for the model, so yours wins. If you swapped the model in [the config](/reference/configuration#models-and-tables), register the policy for your model class. Do the same for `MediaFolder` and `MediaFolderPolicy`.

## The canAccess plugin option

`canAccess()` gates the library page and its navigation item. It does not touch the picker or the policies:

```php
FilamentMediaLibraryPlugin::make()->canAccess(fn (): bool => auth()->user()->can('manage-media'));
```

A user who fails `canAccess()` or `viewAny` gets a 403 on the page. See [Plugin options](/reference/plugin#access).

## Examples

### Staff only

Only staff can upload, and only admins see private files:

```php
public function create(Authenticatable $user): bool
{
    return $user->is_staff;
}

public function viewPrivate(Authenticatable $user): bool
{
    return $user->is_admin;
}
```

The same `create` check protects the chunked upload endpoint and URL import.

### Per-team rules

Inside a tenant panel, [tenancy](/guide/tenancy) already limits the query to the current team. Add a policy rule for who in the team may change files:

```php
public function update(Authenticatable $user, MediaItem $item): bool
{
    return parent::update($user, $item)
        && $user->teamRole($item->tenant_id) !== 'viewer';
}
```

`tenant_id` is the tenant foreign key from [the config](/reference/configuration#key-types).

### Deny everything outside a permission

```php
public function viewAny(Authenticatable $user): bool
{
    return $user->can('media.view');
}
```

## Outside panels

On your own pages the same policies apply, and the default is open to every signed-in user. Register a policy before you enable [`standalone`](/guide/outside-panels). See also [Security](/guide/security).
