Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion content/guides/02.content/4.import-export.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,24 @@ they are exported.
| **Format** | Choose to export items as CSV, JSON, XML, or YAML. |
| **Limit** | Set the maximum number of items to be exported. |
| **Export Location** | Download the export file directly to your machine or to the file library. |
| **Folder** | Choose the Folder to download to (if export location is the folder library). |
| **Folder** | Choose the folder to save to (if export location is the File Library). Defaults to the **Default Exports Folder**, or the **Default Folder** if none is set. |
| **Sort Field** | Choose field to sort items by. |
| **Sort Direction** | Choose to sort items in ascending or descending order. |
| **Full-Text Search** | Limit exported Items to ones which matched as search results. |
| **Filter** | Limit exported items with a filter. |
| **Fields** | Add, remove, and re-order the item fields that will be exported. |

### Exports Saved to the File Library

Exports of 2,500 or more items, or more items than [`QUERY_LIMIT_MAX`](/configuration/security-limits) allows, are processed in batches and always saved to the File Library.

Exports saved to the File Library without a folder go to the **Default Exports Folder** set in **Settings → Files & Storage**. If no Default Exports Folder is set, they go to the **Default Folder**, then the root of the File Library.

The export menu only shows options the current user has permission to use:

- The **File Library** location is only available to users with create access on `directus_files`. If an export is too large to download and the user cannot save it to the File Library, the export is blocked.
- The **Folder** picker is only available to users with read access on `directus_folders`. Other users see a notice stating where the file will be saved.

::callout{icon="i-lucide-triangle-alert" color="warning"}
Exported files are regular files. Anyone with read access to them, including unauthenticated users if the Public policy allows it, can view and download the exported data. Set the Default Exports Folder to a folder the Public policy can't read. See [Scope Public File Access to Specific Folders](/guides/security/best-practices#scope-public-file-access-to-specific-folders).
::
2 changes: 1 addition & 1 deletion content/guides/03.auth/2.access-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ All public permissions are **off by default**. It is up to administrators to re-
::callout{icon="i-lucide-triangle-alert" color="warning"}
Granting collection-level read access to the public role exposes **all items** in that collection to anyone, including unauthenticated users and bots. If that collection contains a mix of published and unpublished content, all of it will be accessible via the API unless you configure additional restrictions.
<br><br>
Review [Minimize the Public Role](/guides/security/best-practices#minimize-the-public-role) in Security Best Practices before enabling public access.
Review [Secure the Public Policy](/guides/security/best-practices#secure-the-public-policy) in Security Best Practices before enabling public access.
::

## Statuses
Expand Down
1 change: 1 addition & 0 deletions content/guides/05.files/5.transform.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ The following options are available:
- **Allowed Transformations**: for enabling, disabling, or limiting image transformations.
- **Default Folder**: sets the default folder where new assets are added. This does not affect existing files. Be aware
that fields may override this value.
- **Default Exports Folder**: sets the default folder where exports saved to the File Library are added.
- **Transformation Presets**: sets a specific image transformation configuration to simplify requests or limit usage.
- **Key**: sets unique identifier allowing faster and easier image transformation requests.
- **Fit**: contain _(keeps aspect ratio)_, Cover _(exact size)_, Fit Inside, or Fit Outside.
Expand Down
71 changes: 66 additions & 5 deletions content/guides/14.security/1.best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,75 @@ Grant all access on `directus_shares` to administrators only.

## Access Control

### Minimize the Public Role
### Secure the Public Policy

The public role applies to every unauthenticated request. Granting read access on a collection to the public role exposes **all items** in that collection to anyone on the internet, including items you might assume are filtered by your frontend.
The **Public policy** applies to every unauthenticated request made to your project. Any permission you grant on this policy is available to anyone on the internet, including visitors, bots, and scripts. Treat every Public permission as world-readable, or world-writable for create, update, and delete.

- Only grant public access to collections that are genuinely intended for unauthenticated consumption.
All Public permissions are off by default. You manage them in **Settings → Access Policies → Public**. The Data Studio shows a warning on this page, and asks you to confirm before saving any change that grants access to a system collection.

#### Grant Only What Unauthenticated Users Need

Read access without a filter exposes **all items** in a collection, including items you might assume are hidden by your frontend.

- Only grant Public access to collections intended for unauthenticated consumption.
- If only a subset of items should be public (for example, published posts but not drafts), use [custom permissions](/guides/auth/access-control#custom-permissions) to restrict which items and fields are accessible.
- Before deploying, test the public endpoints with an unauthenticated request. This is the simplest way to catch unintended exposure.

#### Scope Public File Access to Specific Folders

Read access on `directus_files` controls both the `/files` endpoint, which lists file records, and the `/assets/:id` endpoint, which serves file contents. Granting the Public policy read access on `directus_files` without a filter lets anyone list and download every file in the project.

This includes files you did not upload yourself. When a user exports items to the File Library, Directus stores the export as a regular file. Large exports are always saved to the File Library. A filter-less Public read permission makes these exports, and the collection data inside them, publicly available.

- Never grant the Public policy read access on `directus_files` without a filter.
- Create a dedicated folder for public assets, and add an item rule that limits Public read to that folder:

```json
{
"folder": {
"_eq": "<public-folder-id>"
}
}
```

- Use `_in` with a list of folder IDs if you need more than one public folder.
- Store exports and other internal files outside your public folders. Set the **Default Exports Folder** in **Settings → Files & Storage** to a folder the Public policy can't read, so [exports saved to the File Library](/guides/content/import-export#exports-saved-to-the-file-library) don't land in a public folder or the root. See [Restrict Public File Uploads](#restrict-public-file-uploads) for guidance on Public create access.

#### Avoid Public Permissions on System Collections

System collections (prefixed with `directus_`) store your project's users, configuration, permissions, and activity. Public access to any of them is rarely intended. The risks described in [Restrict Access to System Collections](#restrict-access-to-system-collections) and [Audit Read Access on Sensitive System Collections](#audit-read-access-on-sensitive-system-collections) apply to every unauthenticated request when the permission is on the Public policy.

- Do not grant the Public policy any permission on a `directus_*` collection unless your project requires it.
- If you must grant one, always add an item rule that limits access to the specific records unauthenticated users need, and use field permissions to expose only the required fields.
- Never grant the Public policy create, update, or delete access on a system collection.

::callout{icon="i-lucide-triangle-alert" color="warning"}
Read access without a filter exposes every record in the collection. On a system collection, this can include user details, file metadata, or project configuration.
::

#### Audit Existing Public Permissions

Review the Public policy on existing projects.

1. Open **Settings → Access Policies → Public** and review every collection listed under **Permissions**.
2. Look for any `directus_*` collection. Remove the permission unless your project requires it.
3. For each remaining read permission, confirm it uses a custom item rule rather than full access.
4. Send unauthenticated requests to the endpoints your project exposes and confirm the responses only contain data you intend to be public. For example, the following request, sent without an access token, should return a permissions error or only files from your public folders:

```http
GET /files
```

You can also list every Public permission through the API as an administrator. The Public policy has a fixed ID in every project:

```http
GET /permissions?filter[policy][_eq]=abf8a154-5b1c-4a46-ac9c-7300570f4f17
```

Any result with a `collection` starting with `directus_`, or a read `action` with an empty `permissions` value, needs review.

If you find that `directus_files` was publicly readable, check the File Library for exports that may have been exposed. Exported files use the title format `export-<collection>-<timestamp>`. Move them into a folder the Public policy can't read, or delete them.

### Scope Junction Table Permissions

Junction tables connect two collections in a many-to-many relationship. Unrestricted create access on a junction collection lets a user associate any item on one side with any item on the other, regardless of the permissions on the related collections. A user with create on `posts_tags` can attach any tag to any post, even without read or update access to `posts`.
Expand Down Expand Up @@ -130,9 +191,9 @@ Since password validation runs on the main event loop and is performed whenever

### Restrict Public File Uploads

The public role has no file upload permission by default, and that is the safe choice. Granting the public role create access on `directus_files` lets any unauthenticated request upload arbitrary files to your storage backend, leading to storage exhaustion, delivery of hostile content from your domain, and abuse of your project as an open file host.
The Public policy has no file upload permission by default, and that is the safe choice. Granting the Public policy create access on `directus_files` lets any unauthenticated request upload arbitrary files to your storage backend, leading to storage exhaustion, delivery of hostile content from your domain, and abuse of your project as an open file host.

- Do not grant create on `directus_files` to the public role.
- Do not grant create on `directus_files` to the Public policy.
- Configure [`FILES_MAX_UPLOAD_SIZE`](/configuration/files#upload-limits) and [`FILES_MIME_TYPE_ALLOW_LIST`](/configuration/files#upload-limits) to limit the shape of acceptable uploads.

### Prefer Authorization Headers for Asset Requests
Expand Down
Loading