Skip to content

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 19 May 17:22
· 129 commits to main since this release

Highlights

First public, stable release of CairnCMS. 🎉

CairnCMS 1.0.0 is a GPLv3 fork of Directus v10. The data model, REST and GraphQL APIs, auth flow, permissions, and admin app remain broadly compatible with Directus v10 so existing Directus v10 frontends and integrations should require little or no change.

This release includes modernization, a new look and features, as well as a broad security-hardening pass.

Project Identity And Packaging

  • License. GPLv3, replacing BUSL-1.1.
  • Telemetry removed. No phone-home and no opt-out flag is needed.
  • Package scope. First-party packages publish under @cairncms/*.
  • CLI binaries. cairncms replaces directus; the extension CLI is cairncms-extension.
  • Vendored format-title. @cairncms/format-title replaces @directus/format-title.
  • Local TypeScript config. Replaces the previous @directus/tsconfig shared package.
  • First-party Mapbox styles. Default basemaps now use Mapbox stock styles, removing the dependency on Directus-owned Mapbox style UUIDs.
  • Rebranded admin theme. New brand identity throughout the admin app.

Runtime And Compatibility

  • Node 22 baseline. Minimum Node 22.0.0. (Node 20 is EOL)
  • pnpm 10.x baseline. Minimum pnpm 10.0.0.
  • Supported database vendors in CI. SQLite, PostgreSQL, MySQL, and MariaDB.
  • Vendors dropped from CI. Oracle, Microsoft SQL Server, and CockroachDB still work in code but are no longer covered by automated tests.

New In CairnCMS

  • Config-as-code. Roles and permissions can be exported to and applied from a versioned YAML directory.
  • cairncms init scaffold. npx cairncms init <project> generates a self-contained Docker Compose project with admin credentials, .env, and a starter README.
  • Public-role sentinel. The unauthenticated public role is represented by a reserved UUID row instead of NULL, which simplifies permission uniqueness and removes duplicate-permission merging behavior.
  • First-party JavaScript SDK. @cairncms/sdk is a composable REST and GraphQL client vendored from @directus/sdk, with createCairnCMS and CairnCMSClient as the CairnCMS-facing names.
  • Official Docker images. Multi-arch images publish to Docker Hub at cairncms/cairncms and GHCR at ghcr.io/cairncms/cairncms.
  • Documentation overhaul. Documentation was rewritten end-to-end into Getting started, Guides, Develop, Manage, API reference, and Contributing sections.

Breaking Changes

  • Run Script capability narrowed. The exec flow operation now runs in an isolated-vm sandbox with no require() or host APIs. FLOWS_EXEC_ALLOWED_MODULES is removed; pre-1.0 flows that loaded modules need to be rewritten.
  • Legacy webhooks removed. The Settings > Webhooks page and directus_webhooks collection are gone. Flows are the supported path. Existing records are not auto-migrated. The removal migration logs them at WARN level for manual recreation.

Migrating From Directus 10

These are the changes operators coming from Directus 10 need to account for. Anything not listed here is preserved as-is.

  • Refresh-token cookie name. cairncms_refresh_token replaces directus_refresh_token. Set REFRESH_TOKEN_COOKIE_NAME=directus_refresh_token only if you need compatibility with existing Directus 10 browser cookies; preserving active sessions also requires valid session records and the same SECRET.
  • Messenger namespace. Redis messenger channels now default to cairncms instead of directus. If you run a mixed Directus/CairnCMS Redis-messenger deployment during migration, set MESSENGER_NAMESPACE=directus.
  • /server/info payload. The top-level directus key is now cairncms. Update consumers of response.data.directus.version.
  • SDK factory and client type. createCairnCMS replaces createDirectus; CairnCMSClient replaces DirectusClient. Schema-mirror types and command names are unchanged.
  • Docker paths. Container working directory and default storage paths now live under /cairncms instead of /directus. Update bind mounts. Base image: node:22-alpine.
  • Database table names preserved. directus_users, directus_roles, and the rest of the system tables keep their names. GraphQL system schema names and OpenAPI identifiers derived from those tables are also preserved.

Coming From Directus 11

Directus 11 projects can usually reuse their application tables and content with CairnCMS because CairnCMS exposes collections through REST, GraphQL, files, auth, permissions, flows, and the admin app.

Start with the database schema and content you control. Then recreate or review CairnCMS system configuration in the admin app. Pay particular attention to roles and permissions, because Directus 11 stores access rules through policies and additive permission aggregation while CairnCMS follows the Directus 10 role-permission model.

Review flows, dashboards, presets, extensions, and Directus 11-specific features before relying on them in CairnCMS. Treat application data as the portable part and system configuration as a migration step.

Security Hardening

This release includes a broad security pass across inherited Directus surfaces as well as CairnCMS-specific changes. The most important changes are:

  • Auth surfaces avoid account-state disclosure where unauthenticated callers could distinguish suspended, invited, or unknown accounts.
  • SSO redirects are constrained to safe local paths and parser-bypass regressions are covered.
  • Server-side file imports validate outbound IPs at connection time and block loopback, host-interface, and metadata endpoints by default.
  • Read-derived query features cannot be used as oracles for unread or concealed fields, including search, sort, group, aliases, and value-derived aggregates.
  • Flow revisions redact known secret-bearing keys and values propagated from those keys into later operation options.
  • First-party admin surfaces no longer put bearer tokens in generated asset or export URLs.
  • GraphQL introspection-off mode also gates SDL export surfaces.

Fixes

  • Fixed date-only fields shifting by one day in non-UTC timezones.
  • Restored default DB_CLIENT=sqlite3 bootstrap in the published image.
  • Returned controlled errors for malformed inputs on /auth/password/reset and /utils/hash/verify.
  • Rejected unknown sort field names before SQL generation.
  • Rejected non-object filter query inputs before recursive parsing.
Detailed advisory coverage

Acknowledgements

The CairnCMS codebase originated in Directus v10. Thanks to the Directus team and contributors for the work the project is built on.