From 4688a67f0ee5709abca8e233562399c2d36e0958 Mon Sep 17 00:00:00 2001 From: James White Date: Wed, 20 May 2026 11:56:47 +0100 Subject: [PATCH] add license clarifiation and v12 breaking changes --- app/app.config.ts | 2 +- app/composables/useSectionLinks.ts | 4 +- content/_partials/license.md | 5 +- content/configuration/1.general.md | 17 ++- content/getting-started/2.create-a-project.md | 2 + content/licensing/1.overview.md | 136 ++++++++++++++++++ .../3.breaking-changes/3.version-12.md | 108 ++++++++++++++ content/self-hosting/1.overview.md | 2 +- 8 files changed, 267 insertions(+), 9 deletions(-) create mode 100644 content/licensing/1.overview.md create mode 100644 content/releases/3.breaking-changes/3.version-12.md diff --git a/app/app.config.ts b/app/app.config.ts index f25479e0..ad54de7e 100644 --- a/app/app.config.ts +++ b/app/app.config.ts @@ -235,7 +235,7 @@ export default defineAppConfig({ }, { label: 'License', - to: 'https://directus.io/bsl', + to: 'https://directus.io/MSCL', }, { label: 'Terms', diff --git a/app/composables/useSectionLinks.ts b/app/composables/useSectionLinks.ts index 18670c47..b7550a45 100644 --- a/app/composables/useSectionLinks.ts +++ b/app/composables/useSectionLinks.ts @@ -29,9 +29,9 @@ export default function useSectionLinks() { }, { label: 'Licensing', - href: 'https://directus.io/bsl?ref=directus-docs', + href: '/licensing/overview', icon: 'i-ph-key', - target: '_blank', + active: route.path.startsWith('/licensing'), }, ]; diff --git a/content/_partials/license.md b/content/_partials/license.md index 519bb2e6..58268942 100644 --- a/content/_partials/license.md +++ b/content/_partials/license.md @@ -1,5 +1,4 @@ ::callout{icon="material-symbols:info-outline"} - **Directus requires a license to self-host** - Directus is licensed under a BSL 1.1 for commercial usage. This means you require a license if you are an entity with over $5 million in total finances. Otherwise, you can continue to enjoy Directus in full and commercially without a license. - [Request a license by contacting sales.](https://directus.io/demo) + **Licensing** + Directus is licensed under the [Monospace Sustainable Core License (MSCL)](https://directus.io/MSCL). The free **core tier** does not require a license. Higher limits and additional features require a paid license, or qualifying entities can apply for the [Open Innovation Grant](https://directus.io/oig) for free commercial use. [Learn more about licensing](/licensing/overview). :: diff --git a/content/configuration/1.general.md b/content/configuration/1.general.md index d85f6d3a..268ed827 100644 --- a/content/configuration/1.general.md +++ b/content/configuration/1.general.md @@ -21,8 +21,21 @@ description: Configuration for the general system, server, first admin user, and | `GRAPHQL_SCHEMA_GENERATION_MAX_CONCURRENT` | How many GraphQL schemas can be generated simultaneously. | `5` | | `ROBOTS_TXT` | What the `/robots.txt` endpoint should return. | `User-agent: *\nDisallow: /` | | `TEMP_PATH` | Where Directus' temporary files should be managed. | `./node_modules/.directus` | -| `ACCEPT_TERMS` | Confirm acknowledgement of the [Directus BSL License 1.1](https://directus.io/bsl) and disable the license welcome banner. | `false` | -| `PROJECT_OWNER` | Registered owner and primary contact responsible for your Directus instance. We need this to ensure compliance with our [BSL 1.1 license](https://directus.io/bsl). | | +| `ACCEPT_TERMS` | Confirm acknowledgement of the [Monospace Sustainable Core License](https://directus.io/MSCL). | `false` | +| `PROJECT_OWNER` | Registered owner and primary contact responsible for your Directus instance. | | + +## License + +See [Licensing](/licensing/overview) for a full explanation of license keys, license tokens and source precedence. + +| Variable | Description | Default Value | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `LICENSE_KEY` | License key in the format `DXXXX-XXXXX-XXXXX-XXXXX-XXXXC`. Activated against the Directus licensing service on first use and revalidated periodically. Takes precedence over `LICENSE_TOKEN` and any key set through the Studio. | | +| `LICENSE_TOKEN` | Pre-issued license token for offline use. Validated locally on each startup and never contacts the licensing service. Mutually exclusive with `LICENSE_KEY` — setting both is a configuration error and Directus will refuse to start. | | + +::callout{icon="material-symbols:info-outline"} +When `LICENSE_KEY` or `LICENSE_TOKEN` is set in the environment, the Studio license editor is read-only. To change the license, update the environment variable and restart Directus. +:: ## Server diff --git a/content/getting-started/2.create-a-project.md b/content/getting-started/2.create-a-project.md index cbe5e5d6..1177d83d 100644 --- a/content/getting-started/2.create-a-project.md +++ b/content/getting-started/2.create-a-project.md @@ -9,6 +9,8 @@ There are several ways to start a new Directus project. This guide walks through If you want to compare all deployment paths (including one-click platform guides like Railway), see [How to Deploy Directus](/tutorials/self-hosting). +New self-hosted instances run on the core tier by default. To unlock higher limits or additional features, [add a license](/licensing/overview). + :partial{content="license"} ## Directus Cloud diff --git a/content/licensing/1.overview.md b/content/licensing/1.overview.md new file mode 100644 index 00000000..e04ff0ad --- /dev/null +++ b/content/licensing/1.overview.md @@ -0,0 +1,136 @@ +--- +title: Overview +headline: Licensing +description: How Directus licensing works, how to add a license, and what happens when you exceed your plan. +navigation: + title: Overview +--- + +Directus is licensed under the [Monospace Sustainable Core License (MSCL)](https://directus.io/MSCL). Self-hosted instances without a license run on the **core tier**. To unlock additional capabilities or higher limits, add a license to your instance. + +Free commercial use is available through the **[Open Innovation Grant](http://directus.io/oig)** for entities with less than $5M in annual revenue and fewer than 50 employees. Eligibility is assessed based on the legal entities whose representatives log into the Directus Studio. Full terms are set out in the grant usage agreement. + +## License Keys and License Tokens + +There are two ways to authenticate a license: + +- **License key** — a string in the format `DXXXX-XXXXX-XXXXX-XXXXX-XXXXC`. On first use, it binds your license to a specific project and `PUBLIC_URL`. License keys can be set via environment variable or added through the Studio. +- **License token** — a pre-issued token containing your entitlements, validated locally without contacting the licensing service. Tokens are only set via environment variable and are intended for **offline use**, in environments without outbound network access. + +You configure one or the other — not both. Setting both in your environment is a configuration error and Directus will refuse to start. + +::callout{icon="material-symbols:warning-rounded" color="warning"} +**Offline license tokens are only available on Enterprise plans.** Most self-hosted instances should use a license key. The core tier has no license to validate and can be run air-gapped without a token — only paid plans that need to run without outbound network access require one. +:: + +## License Modes + +### Online Mode + +In online mode, your instance periodically revalidates with the Directus licensing service. Feature access, plan upgrades, and revocations propagate without restarting. Adding a license key through the Studio validates instantly. + +This is the default mode and is appropriate for any instance with outbound network access. + +### Offline Mode + +In offline mode, the instance never contacts the licensing service. Validation happens locally against the token's signature and expiry. This is intended for air-gapped or restricted-network environments on paid plans. + +Because offline instances cannot be reached, suspension or cancellation only takes effect when the token expires. New tokens must be issued and deployed manually. + +Offline mode is only available on Enterprise plans. If you are running the core tier, you do not need a token — Directus has no license to validate. + +## Configuration + +Licenses are configured through one of three sources, applied in the following order of precedence: + +| Source | Precedence | UI editable | +| --- | --- | --- | +| `LICENSE_KEY` (environment) | 1 | No | +| `LICENSE_TOKEN` (environment) | 2 | No | +| License key in database (set via Studio) | 3 | Yes | + +When a key or token is set in the environment, the Studio license editor is read-only — to change it, update the environment variable and restart. + +If no license is configured, the instance runs on the core tier. + +## License Statuses + +| Status | Meaning | +| --- | --- | +| **Active** | License is valid and the instance is within its entitlement limits. | +| **Grace** | License has passed its expiry or the instance has exceeded its limits, but the configured grace period has not yet elapsed. The instance continues to operate normally. | +| **Expired** | The license expired and the grace period has elapsed. Requires renewal. If usage is within core limits, the instance is automatically downgraded to the core tier. | +| **Suspended** | The license has been suspended by Directus. Requires resolution with Directus. If usage is within core limits, the instance is automatically downgraded to the core tier. | +| **Cancelled** | The subscription has been cancelled. The instance is downgraded to the core tier. | +| **Locked** | The instance has exceeded its entitlement limits and is outside any applicable grace period. Requires resolution before normal operation can resume. | + +::callout{icon="material-symbols:info-outline"} +**Enforcement never deletes data.** When limits are exceeded or a license is downgraded, Directus restricts access by deactivating resources or blocking endpoints — your data is never removed. +:: + +## Managing Your License + +Admins can manage their license from **Settings > License** in the Studio. From this screen you can: + +- Add or replace a license key. +- View your current plan, status, and usage against each entitlement. +- Purchase, adjust, or remove addons for plans that support them. +- Open the Stripe customer portal to manage billing, payment methods, and your subscription. + +If your license key is set via the environment, the Studio shows the current entitlements but the editor is locked. To change or remove the key, update the environment variable and restart Directus. See [Activations and project bindings](#activations-and-project-bindings) below for the full deactivation flow. + +## Activations and Project Bindings + +On first use, a license key creates an **activation** on the Directus licensing service, binding the license to your Directus instance at its current `PUBLIC_URL`. This binding is used to authenticate all subsequent revalidation requests for that instance. + +A single license key may be activated against multiple instances at different `PUBLIC_URL`s, depending on your license. + +### Deactivating a License + +Deactivating a license frees its activation on the licensing service so the binding can be reused. + +- **Studio-managed license** — open **Settings > License** in the Studio and click **Deactivate License**. The instance drops to the core tier immediately. +- **Env-managed license** — remove the `LICENSE_KEY` (or `LICENSE_TOKEN`) value from your environment and restart Directus. The Studio license editor becomes available, but the previous plan and entitlements remain displayed until you click **Deactivate License**. + +::callout{icon="material-symbols:warning-rounded" color="warning"} +**Removing the env var alone does not deactivate the activation on the licensing service** — the deactivate action does. If you skip the deactivate step, the activation remains bound to this instance and continues to count against your license's activation limit. +:: + +### Moving an Instance to a New URL + +If you change the `PUBLIC_URL` of an existing instance — for example, when migrating to a new domain — the license key will register a new activation against the new URL. The previous activation against the old URL remains in place until you deactivate it. + +To reuse the same license on the new URL without exceeding your license's activation limit, deactivate the license on the old instance **before** bringing the new one online. + +## Resolution Flow + +If your instance exceeds its entitlements — for example, after downgrading a plan — the Studio surfaces a **Resource Resolution** screen for admins. This screen lists each entitlement that requires action: + +- **Limit-based** entitlements show your current usage, the new limit, and a list of candidate records to deactivate. +- **Feature-gated** entitlements (such as SSO) show any blockers that must be resolved before the feature can be disabled — for example, admin accounts that need an email and password before SSO can be turned off. + +Selecting candidates and submitting the resolution brings the instance back within its entitlements. Resources are deactivated rather than deleted, and the acting admin is always excluded from seat resolution. + +## Locked-Down Instances + +If an instance is over its entitlement limits and the grace period has elapsed, it enters a **locked-down** state. While locked down: + +- The REST `/items`, `/files`, and `/flows` endpoints are disabled. +- The GraphQL, WebSockets, and MCP APIs are disabled. +- `/login` is blocked for non-admin users. +- SSO continues to work for admins so the license can be resolved. + +Resolving the license — either by adding a valid key, reducing usage through the resolution flow, or purchasing addons — restores normal operation. + +## Upgrading to Directus 12 + +::callout{icon="material-symbols:info-outline"} +**Existing customers** should contact [licensing@directus.io](mailto:licensing@directus.io) to obtain your license before upgrading, or if you encounter any issues. +:: + +When an existing instance upgrades to Directus 12 without a license, behavior depends on current usage: + +- **Within core tier limits** — the instance continues to operate on the core tier. +- **Above core tier limits** — the instance enters a 30-day grace period during which it continues to function normally. Admins see a reminder on every login. Add a license key to clear the reminder, or reduce usage to within core limits before the grace period ends. + +If the grace period ends with usage still above core limits, the resolution flow is triggered on next admin login. diff --git a/content/releases/3.breaking-changes/3.version-12.md b/content/releases/3.breaking-changes/3.version-12.md new file mode 100644 index 00000000..2a703697 --- /dev/null +++ b/content/releases/3.breaking-changes/3.version-12.md @@ -0,0 +1,108 @@ +--- +title: Version 12 +description: Breaking changes may require action on your part before upgrading. +--- + +## Version 12.0.0 + +Jump to: + +- [License Enforcement](#license-enforcement) +- [Draft Publishing Workflow](#draft-publishing-workflow) +- [Extension Compatibility](#extension-compatibility) + +### License Enforcement + +Directus 12 introduces active license enforcement. Self-hosted instances run on the **core tier** by default. Higher limits and additional features are unlocked by configuring a license. See [Licensing](/licensing/overview) for a full explanation. + +#### Post-upgrade Grace Period + +The grace period exists to ensure uninterrupted service for existing customers who upgrade before obtaining a license. If your instance is above core tier limits when you upgrade to Directus 12, you enter a **30-day grace period** during which everything continues to operate normally. Admins see a reminder on every login. + +::callout{icon="material-symbols:info-outline"} +**Existing customers** should contact [licensing@directus.io](mailto:licensing@directus.io) to obtain your license. This is the right action for any existing customer who has not yet received a license, or upgrades and sees the grace period reminder. +:: + +If you are not an existing customer and do not intend to add a license, reduce usage to within core limits before the grace period ends. Note that free commercial use may be available through the [Open Innovation Grant](http://directus.io/oig). + +If the grace period ends with usage still above core limits, the resolution flow is triggered on next admin login and certain APIs are locked down until resolved. + +#### Locked-Down Behavior + +When an instance is over its entitlement limits and the grace period has elapsed: + +- The REST `/items`, `/files`, and `/flows` endpoints are disabled. +- The GraphQL, WebSockets, and MCP APIs are disabled. +- `/login` is blocked for non-admin users. +- SSO continues to work for admins so the license can be resolved. + +No data is deleted as a result of enforcement — access is restricted via deactivation or blocking only. + +### `status` Field Added to Collection and User Responses + +`GET /collections` responses now include a `status` of `active` or `inactive` in each item's `meta` object. Inactive collections are those deactivated by license enforcement. + +`GET /users` responses can now return a new `inactive-license` status in addition to the existing user statuses (`draft`, `invited`, `unverified`, `active`, `suspended`, `archived`). Users with this status have been deactivated because the instance is over its seat entitlement. + +### Draft Publishing Workflow + +#### Published items in versioned collections are now locked from direct editing + +In collections with content versioning enabled, published items can no longer be edited directly. To make changes, switch to the draft version using the new header action button. The Studio also handles this transition automatically: + +- Creating a new item in a versioned collection opens a virtual draft. The URL takes the form `collection/+?version=draft`. +- Editing a published item in a versioned collection automatically switches the editor context to draft mode. + +#### `?version=main` renamed to `?version=published` + +The query parameter used to retrieve the published version of an item is now `?version=published`. The previous `?version=main` value continues to work, so existing integrations are not broken — but new code should use `?version=published`. + +#### Collection status replaced with an `archived` boolean + +The collection-level `status` string has been replaced with an `archived` boolean for newly created collections. Existing collections that use the string-based `status` field continue to work as before, so no migration is required. + +#### Publishing a version no longer requires a second confirmation + +Publishing a version previously required two confirmations — one in the comparison modal, and a second confirmation dialog after it. The second dialog has been removed: confirming the changes in the comparison modal now publishes the item directly. + +### Extension Compatibility + +The Studio has had a design refresh in Directus 12. Most extensions are unaffected, but theme and interface extensions may need updates. The following notices are grouped by area. + +#### Removed and replaced theme properties + +The following theme properties have been removed. Theme extensions that reference them will continue to load but the affected styling will no longer have any effect. + +| Removed | Replacement | +| --- | --- | +| `navigation.background`, `navigation.backgroundAccent`, `navigation.borderWidth`, `navigation.borderColor` | `shell.background`, `shell.backgroundAccent`, `shell.borderWidth`, `shell.borderColor` | +| `header.background`, `header.borderWidth`, `header.borderColor` | Same `shell.*` tokens as above | +| `header.headline.foreground`, `header.headline.fontFamily` | Removed without replacement | +| `headerShadow`, `sidebarShadow` (`LayoutConfig`, `defineLayout()`) | Removed without replacement | +| `boxShadow` (header theme rules schema) | Removed without replacement | +| `section.toggle.borderWidth`, `section.toggle.borderColor` | Section-level border tokens | +| `navigation.project.borderColor`, `navigation.project.borderWidth`, `navigation.project.background` | Removed without replacement | +| `borderColorFocus`, `boxShadowHover`, `boxShadowFocus` | Migrate to focus ring tokens (see below) | + +CSS variable migrations: + +- `--theme--navigation--*` and `--theme--header--*` → `--theme--shell--*` +- `--theme--form--field--input--border-color-focus` and `--theme--form--field--input--box-shadow-focus` → `--theme--form--field--input--focus-ring-color` + +The focus ring is now implemented via the CSS `outline` property rather than border/box-shadow. + +#### Component deprecations + +The following components and props have been deprecated. Existing usage continues to function — extensions will see Volar hints — but should be migrated. + +- `` — migrate to `@directus/vue-split-panel` or an alternative. +- `` — deprecated globally. +- ``: the `subtitle` prop, `subtitle` slot, `header:append` slot, and `actions:append` slot. Use the new `actions:primary` slot for primary call-to-action components. +- `v-button` `rounded` prop — removed. Existing usage continues to function but buttons render as rounded rectangles instead of circles. + +#### Slot deprecations on the header bar + +The private view header bar has changed: + +- The `#headline` slot has been deprecated. +- The `actions:append` slot has been deprecated. Existing usage still renders in the secondary-actions zone, but should be migrated to the new `actions:primary` slot. diff --git a/content/self-hosting/1.overview.md b/content/self-hosting/1.overview.md index 708c5307..68e63ec4 100644 --- a/content/self-hosting/1.overview.md +++ b/content/self-hosting/1.overview.md @@ -27,7 +27,7 @@ If you have experience running and scaling Docker containers, are able to monito :partial{content="license"} -On top of the Directus license, you will need to consider the cost of your infrastructure, including the server, database, and other dependencies. The non-exhaustive list of considerations includes: +Beyond any Directus license costs, you will need to consider the cost of your infrastructure, including the server, database, and other dependencies. The non-exhaustive list of considerations includes: - Compute (running the Directus instance) - Database