From d0d017b48c689061d474d157ced4be46cdb8d219 Mon Sep 17 00:00:00 2001 From: James White Date: Wed, 23 Sep 2026 14:43:04 +0100 Subject: [PATCH] versioning permission clarifications --- .../guides/02.content/6.content-versioning.md | 23 ++++++++++++++++--- .../guides/14.security/1.best-practices.md | 5 ++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/content/guides/02.content/6.content-versioning.md b/content/guides/02.content/6.content-versioning.md index e7a15a5d..2f92e371 100644 --- a/content/guides/02.content/6.content-versioning.md +++ b/content/guides/02.content/6.content-versioning.md @@ -28,6 +28,25 @@ The version field is a dynamic variable can be added to the live preview URL so Navigate to **Settings** > **Data Model**, select the collection that you want to enable content versioning for, and scroll down to the content versioning section. Toggle "Enable Versions" and save your data model. +### Permissions + +Directus stores versions in the `directus_versions` system collection and tracks each change in `directus_revisions`. Enabling versioning on a collection does not grant access to either of these collections, and non-administrator users have no access to them by default. The Studio needs access to both before editors can create, save, or publish content in a versioned collection. + +Grant the following to every policy used by editors of a versioned collection. This is the minimum set for the Studio to behave predictably. + +| Collection | Permissions | Notes | +|---|---|---| +| Your versioned collection | Read, Create, Update | Create publishes new drafts, Update publishes changes to existing items. | +| `directus_versions` | Read, Create, Update, Delete | Grant all fields and no item rules. Delete lets Directus remove a version after publishing and lets editors discard drafts. | +| `directus_revisions` | Read | Used by the Publish comparison and the revisions sidebar. Scope it with an item rule on `collection` to match the collections the policy can read. | + +::callout{icon="i-lucide-info"} +**Incomplete permissions** +If any of these permissions are missing, editors may see unexpected behavior, such as a disabled **Create** button, a read-only form, edits that do not save, or a "Forbidden" error when publishing. +:: + +Applications that read versioned content through the API, such as live preview frontends, only need read access to `directus_versions` and to the collection. For guidance on limiting access to these system collections, see [Security Best Practices](/guides/security/best-practices#revisions--versions). + ## Editing Versioned Items When content versioning is enabled for a collection, the published view is **read-only**. Fields are disabled and no Save button is shown. This enforces a draft-first workflow — all edits go through a version before reaching the published item. @@ -128,8 +147,6 @@ Versions can be saved even if required fields are empty. Validation of required Publishing a version makes it the published (current) version of your content. -Publishing a version makes it the published (current) version of your content. - ### How to Publish a Version 1. Open the version you want to publish @@ -148,7 +165,7 @@ If the version has missing required fields, Directus will display field-level va Once published, this version becomes the active content, and the previous published item is preserved in the version history. -After publishing a version, you can choose to keep or delete the version. For the global draft version, you'll see options to "Discard Edits" or "Keep Edits" instead of "Delete Version" or "Keep Version". +After publishing, Directus deletes the version automatically when your policy allows deleting `directus_versions`, and the draft version returns to its empty state. Without delete permission, the version is kept with its changes and continues to appear in draft mode. ::callout{icon="i-lucide-info"} **Programmatically Implement Content Versioning** diff --git a/content/guides/14.security/1.best-practices.md b/content/guides/14.security/1.best-practices.md index ec89eef3..48733348 100644 --- a/content/guides/14.security/1.best-practices.md +++ b/content/guides/14.security/1.best-practices.md @@ -77,8 +77,9 @@ Grant read on `directus_activity` to administrators only, or scope it with an it Revisions and versions store snapshots of item data at the time of each change. Reading `directus_revisions` or `directus_versions` returns the content of those snapshots, which bypasses the current read permissions on the source collection. -- Grant read on `directus_revisions` and `directus_versions` to administrators only. -- If you need to expose revisions for a specific collection, scope with an item rule that matches the collection and mirrors the user's read permissions on the source collection. +- Grant read on `directus_revisions` and `directus_versions` only to administrators and to editors of collections with [content versioning](/guides/content/content-versioning#permissions) enabled. Those editors also need create, update, and delete on `directus_versions`, or the Studio cannot create, save, or publish versioned content. +- Scope read on `directus_revisions` with an item rule on the `collection` field that matches the collections the policy can already read. +- Avoid item rules on `directus_versions`. An item rule on the update permission can prevent editors from saving new drafts. ### Sessions