Skip to content

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):

AbilityDefault
viewAnyAllowed for any signed-in user.
viewAllowed for the uploader, for any non-private file, and for users who pass viewPrivate.
createAllowed for any signed-in user.
updateSame as view.
deleteSame as view.
restoreSame as view.
forceDeleteSame as view.
viewPrivateDenied 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, 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.

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 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.

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. See also Security.

Commercial licence. One licence per production project. Terms · Privacy · Refunds