---
url: /guide/private-files.md
description: >-
  Mark files and folders Only me, decide who can see them with the viewPrivate
  ability, and understand signed links and the public-disk caveat.
---

# Private files

Every file and folder is either **Shared** or **Only me**. Shared is the default. A private record is visible only to the user who created it, and to users who pass the `viewPrivate` ability.

## Make something private

* **A file**: change **Visibility** in the [inspector](/guide/inspector), or select files and use **Visibility** in the bulk bar.
* **A folder**: choose **Visibility** when you create the folder, or in **Edit folder**.

Uploads start as Shared. A private folder does not change the visibility of the files inside it; set those separately. Private files show a lock badge, and private folders are labelled Only me.

## Who sees what

| Person | Private files and folders |
|---|---|
| The uploader (or folder creator) | Sees, edits, moves and deletes them. |
| A user passing `viewPrivate` | Sees and manages every private record. |
| Everyone else | Does not see them in the library, in pickers, in search, or in counts. |

The same rule applies on the server. A form field rejects the id of a private file the user cannot see, downloads skip it, and the library actions refuse it. A folder that holds someone else's private content cannot be deleted by a user who cannot see it.

## Grant `viewPrivate`

The bundled `MediaItemPolicy` returns `false` for `viewPrivate`. Extend it, return `true` for the people who need it, and register your policy:

```php
namespace App\Policies;

use Hoceineel\FilamentMediaLibrary\Policies\MediaItemPolicy;
use Illuminate\Contracts\Auth\Authenticatable;

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

```php
use App\Policies\AppMediaItemPolicy;
use Hoceineel\FilamentMediaLibrary\Models\MediaItem;
use Illuminate\Support\Facades\Gate;

public function boot(): void
{
    Gate::policy(MediaItem::class, AppMediaItemPolicy::class);
}
```

The library registers its own policies only when you have not. `update`, `delete`, `restore` and `forceDelete` follow `view`, so a user with `viewPrivate` can also change and delete other people's private files. Folders use `MediaFolderPolicy` with the same `viewPrivate` check. See [Authorization](/reference/authorization).

## Links to private files

A private file never gets a permanent URL. Wherever the library needs a link, it creates a short-lived one:

* On a **private disk** that supports temporary URLs, such as S3, it is a temporary URL.
* On a disk set to `'visibility' => 'public'`, it is a signed link to the library's serve route, `/media-library/serve/{uuid}`. That route refuses a private file unless the link carries a valid signature, and it returns 404 for anything in the trash.

Links last `temporary_url_minutes`, which is 30 by default. They are cached for half that time so a page of thumbnails does not sign every file again. A private file has no `srcset`, because responsive variants would each need a link.

This has three consequences:

* Do not use a private file on a public page. Its link stops working after it expires.
* If you make a Shared file private later, permanent signed links already published for it stop working on a private disk. On a public disk the direct file URL keeps working, which is the caveat below.
* **Copy link** in the inspector copies a link that expires.

## Rich text cannot embed private files

The [rich editor](/guide/rich-editor) stores image URLs inside the saved content, so they must not expire. Private files have no permanent URL, so the plugin skips them when you insert. Make the file Shared first if it belongs in rich text.

## The public-disk caveat

::: warning Private files are only confidential on a private disk
Files are stored under random UUID folders, so their URLs cannot be guessed or enumerated. On a disk with `'visibility' => 'public'`, though, the file still sits in a web-readable folder. Anyone who already has the exact URL can open it, and a copied path stays valid.
:::

The library's signed links protect the page that lists the file. They do not move the file. When private files must stay confidential, point `disk` at a private disk, for example S3 with private visibility, or a `local` disk outside `public/`:

```php
'disk' => env('MEDIA_LIBRARY_DISK', 's3'),
```

Keep `conversions_disk` on a private disk too if you set it. See [Storage](/guide/storage).

## Turn it off

Set `private_media` to `false`, or disable the feature on the plugin:

```php
use Hoceineel\FilamentMediaLibrary\Enums\Feature;
use Hoceineel\FilamentMediaLibrary\FilamentMediaLibraryPlugin;

FilamentMediaLibraryPlugin::make()
    ->disableFeatures(Feature::PrivateMedia);
```

The **Visibility** controls disappear. Files already marked **Only me** become visible to everyone who can open the library, so decide what to do with them before you switch it off.

Next: [Keyboard](/guide/keyboard).
