Code-first configuration of schema, roles and permissions #13041
Replies: 37 comments 41 replies
-
The schema can probably be managed by,
There is also a command for creating roles I'd love to see the concept extended to the permissions. It'd be useful to have named permission groups that can be mapped to roles. |
Beta Was this translation helpful? Give feedback.
-
I'd love to see this supported too. I wonder how this approach could be added to align with our current strategy... |
Beta Was this translation helpful? Give feedback.
-
One idea could be to expose the same file permission structure that Directus uses for AppMinimumPermissions, thus allowing developers to add permissions in code and also have them applied. This still allows making use of the UI to add additional permissions by business if wanted. Use case: |
Beta Was this translation helpful? Give feedback.
-
We would love to see this! |
Beta Was this translation helpful? Give feedback.
-
Permissions are usually applied to a specific role, although with coded config, we could allow for a more flexible structure such as extended roles and shared permissions between different roles. How does this look: Roles
PermissionsFILE NAME CORRESPONDS TO COLLECTION NAME Single role example
Multiple role example
|
Beta Was this translation helpful? Give feedback.
-
It only updates (deletes and inserts) permissions for those collections
that there are config files for.
Since each permission should be unique per action, collection and role, it
updates those that match those three columns,and removes the others.
Collections that do not have config file are not touched.
…On Wed, 4 May 2022, 16:06 Rijk van Zanten, ***@***.***> wrote:
Would this also remove every other permissions record from the database
during sync, or would these records be additional? (Eg would the file
become the single source of truth?)
—
Reply to this email directly, view it on GitHub
<#13041 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABSVMWWXZTBFY54OMJH27PTVIJ77PANCNFSM5URUBLOA>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I think „Advanced custom fields” has solved this pretty well in the wordpress universe. It initially allows you to configure everything via UI, the config is stored in the db and optionally also to a local json file afterwards. Then on each load it compares the database and file values and if they do not match it shows a Sync-Option including an comparisons overview. This could also solve the problem that ist’s pretty hard to track and review permission changes. A link to their documentation with some more details: https://www.advancedcustomfields.com/resources/local-json/ |
Beta Was this translation helpful? Give feedback.
-
I'm seeding initial roles, permissions and users in a custom migration. |
Beta Was this translation helpful? Give feedback.
-
#16101 Here is a PR for splitting the schema file and allowing you to more easily push only the changes you want to push to git. |
Beta Was this translation helpful? Give feedback.
-
From a developer's perspective, this is a critical feature. With most ORMs, you define your schema in a single location, and they auto-generate tables/code/etc. For my current workflow, I create TypeScript interfaces first, then I have to create the actual schema in the UI. Plus it makes migrations and deployments more difficult. This is repetitive and tedious. In a perfect world, I'd love to see an ORM approach using decorators (similar to TypeORM or VuexORM). Something like ... import { Item, collection, field, role } from '@directus/schema'
@collection({
name: 'jobs',
icon: 'ads_click',
note: 'A collection for displaying jobs',
display_template: '{{title}}',
})
@role('employer', {
permissions: ['read', 'create', 'update', 'delete'],
// Employers can only update their own records
validation: { company: { _eq: '$CURRENT_USER.company' } },
})
class Job extends Item /* Provides base fields, created/updated, status, etc. */ {
@field({
is_primary_key: true,
auto_increment: true,
})
id: number
@field({
interface: 'input',
max_length: 50,
trim: true,
})
title: string
} You could then define all of your collections/fields/roles/permissions/etc. in local code alongside your models, and have them automatically synced without ever having to touch the UI. |
Beta Was this translation helpful? Give feedback.
-
I really like this idea of code config; in fact, in the absence of this functionality, we are using migrations to apply changes across all environments. But it is quite uncomfortable. |
Beta Was this translation helpful? Give feedback.
-
Before I found Directus was working with Drupal for years. One of the few things where Drupal has an advantage over Directus is configuration management - it's not perfect BUT it has been battle-tested over a period of many years in every environment and project setup you can imagine. Drupal has a concept of "content types" that are basically database tables (but the structure is mind blowingly complicated) to which you can add fields of different types and with different display modes. They have found a quite clear distinction between configuration and content, and they have built in the option of overriding config per environment (for example an extra set of modules for developers that are only active in development; production specific configuration only in production). I think you could benefit from getting inspiration from that project; either by looking at documentation/code and/or by discussing the implementation (and challenges they've overcome!) with some of the developers. |
Beta Was this translation helpful? Give feedback.
-
Heya! Thanks for opening this feature request! This feature request has received over 15 votes from the community. This means we'll move this feature request to the Under Review state! The Core team will schedule a meeting to review this request as soon as possible. The discussion will then be approved or denied. You may or may not be invited to join this meeting with the core team. For more information, see our Feature Request Process. |
Beta Was this translation helpful? Give feedback.
-
Dear reader, also make sure to take a look at #17495, which discusses the same goals in slightly different ways 🙂 |
Beta Was this translation helpful? Give feedback.
-
Very exiting seeing this suggestion (and #17495) making it into Review :-)! I was just reflecting on the original title "Code-first configuration of schema, roles and permissions". I just wanted to iterate that it wasn't being able to work with code (instead of the UI) that was the primary objective (as the title may imply), but more as mentioned in #17495 - supporting a team-friendly, versionable, reviewable, multi-environment deployment workflow for both schema and configuration. A workflow that allows developers to configure Directus locally and review/deploy changes via a CI/CD workflow. I think it makes sense to be able to configure which parts of the configuration are considered "application logic" on a per-project basis. |
Beta Was this translation helpful? Give feedback.
-
What's the expected way for us to approach this issue right now? Are there any examples online of actual code bases using stuff like custom migrations with knex and schema snapshots? |
Beta Was this translation helpful? Give feedback.
-
Ideal would be generating diff migrations thereby no matter the state of environment you would be able to run migrations in correct order. Both full snapshots (for test ci/cd) and diff snapshots (for live environments) should be supported. |
Beta Was this translation helpful? Give feedback.
-
We've been using diff migrations for a while and that issue with the Directus and custom migrations order that @u12206050 mentioned has bitten us. We had to edit some of the historic migrations to get it to work on a new Directus instance. How ours works:
It generally works pretty reliably, we want to update the cli command to output js/ts with the full migration script to save the manual step, but we've been holding back to see the direction of any official/recommended approach. We also look through the diff before committing to make sure the right collections / fields are being modified. The issues we do have with it are related to our workflow. We have local environments, a shared dev instance, staging and production. No manual schema changes should be made on staging or production. Our backend developers work locally and often create new collections using a derivative of the schema builder kit, which allows us to create custom migrations easily. which are more compact and legible than the diff approach above. It doesn't support modifiying fields or collections yet so we use diff approach for that. We also have frontend developers that use the data studio on the shared dev instance of directus to add collections, fields and relationships. When they are ready to deploy those changes, a backend developer fetches a snapshot from the dev instance (now using the endpoint, previously using the cli) and runs the diff command mentioned above. There is the manual step of making sure everything in the diff can make it's way to prod, sometimes there are changes from other developers which are not ready, so we don't yet have an easy way to isolate those changes from the diff. Once the diff is ready, it gets added to the migrations but probably the main issue is that the diff is created between the local instance which should match production and the snapshot for the dev instance. However, once the migration is pushed to git, the CI builds the directus image and as part of our pipeline it gets deployed to our dev instance. So by default, the diff migration would fail as those changes are already present. We don't yet have an elegant way to mark the migration as effectively run, but do have a workaround in place not to have the migration fail. We do run other instances for specific isolated features, but it is difficult to keep them in sync with the regular pipeline, if we have them on the same codebase then they have to run the diff migrations which we may not want, but there may be other changes we do want. In summary, while it is working ok for us, we'd consider a declarative approach as it may work better in our workflow. The currenet snapshot approach does fail though for us as the file is too large due to the number of collections we have. Even if we split the files up, the way that the apply snapshot process deletes collections that are missing from the snapshot would likely cause issues for us as we deploy into multiple environments. For instance every change on a local instance would need to fetch the current dev snapshot (some of which may be a work in progress), otherwise when it gets deployed to dev it would wipe out all the recent changes there. Then of course there are the issues with permissions, flows, and content which we have a different sync process which is still a work in progress. |
Beta Was this translation helpful? Give feedback.
-
I have experience working with Django and another headless CMS in the past and I like how the migrations/developer-flow is handled in both. In Django, first you define the schema in files and run a command to generate a migration file. Basically, a migration file is just instructions to apply the changes necessary without, relying on another environment state. This is important because once you have multiple developers working on a project the snapshot could get out of sync at any point. See makemigrations, migrate. Also, one feature is really helpful when developing is unapplying migrations migrate which allows you to rollback the schema to a certain state. In the other headless cms, there is a concept of branches where you can create a copy of the current environment (a new branch), make schema changes on the UI, connect to the new branch as a developer and testing on my client. After done development, I can either merge those changes back the main branch or download a migration file. Downloading the file is amazing because it allows me to:
I still prefer the idea of starting to create schema changes, adding roles, or configure permissions on the UI rather than generating migration files manually because I love Directs UI and it is way faster/easier to create, setup and experiment. I have been experimenting with DrizzleORM recently to manage migrations outside of Directus just to find out how this could be managed. I did the following so far:
Looking forward to see this implemented in Directus 🌟 |
Beta Was this translation helpful? Give feedback.
-
SummaryAdd Directus code first configuration management to the current API/App features to enable better devops, templating, environment migrations and general reusability of any project. Currently schemas, roles and permissions are configured in the APIs or Studio App and stored in the database. It is of course possible to create schema snapshots and export permissions and roles via the API, however this approach does not fit naturally into a DevOps flow with multiple developers and multiple environments. The general idea is that schemas, roles and permissions could be developed in code (e.g. yaml) and applied to the database the next time directus is started. An extension of this would be that changes made via the UI (locally) are reflected back to code and can be reviewed and committed to source control. Applying changes to production could be part of a CI/CD pipeline (e.g. Github Actions) which could use the directus API. Basic ExampleCode first concept(similar to the current custom extensions implementation): A group of config folders:
When populated by one or more yml files inside, Directus will apply to project & database MotivationUse Cases:
Detailed DesignRequirements ListMust haves:
Should haves:
Could haves:
Will not have:
|
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
Hi, I've just built a tool called directus-sync that could help streamline the way we handle Directus configurations and schema management. It’s inspired by the principles of infrastructure-as-code, with a touch of the familiar workflow from Terraform. This is currently a beta release, and I’m seeking collaborators who are up for testing, providing feedback, and contributing to its evolution. Check out the repo and let me know what you think! |
Beta Was this translation helpful? Give feedback.
-
On January 25 we're inviting you to come and have a chat with us about this feature request at our Request Review in our Discord server. This will help us have some dedicated time to talk about what implementation would have the most sense. Please feel free to join us as https://directus.chat (the event is already listed and you can set a reminder) |
Beta Was this translation helpful? Give feedback.
-
NOTES: January 25, 2024 Request Review
Recording of the session will be available on Directus TV in a few days: |
Beta Was this translation helpful? Give feedback.
-
This has been solving our needs in 5 of our DIrectus projects so far with a team of 5 users: https://github.com/bcc-code/directus-schema-sync Also if you need to start from scratch (ie. testing environment in Docker) we have this script that installs Directus and import schema and data from schema-config on a fresh database: Download the init.mjs file and add it to the project root then in package.json under scripts add |
Beta Was this translation helpful? Give feedback.
-
Looks like Apple just released a configuration as a code language named Pkl, might be something useful to keep an eye on. From their use cases:
From their concepts:
if I understand this part correctly it could be useful to us to define a single source of truth for things like official Directus's collections making them readable, referenceable and expandable. This language's strong points seems to be about: Schema generation, Modularity, Templating and Type safety. Basically one of the two aspects we needed for this discussion, leaving only the "data" question to be solved. |
Beta Was this translation helpful? Give feedback.
-
Locked ModeThere should also be a locked mode, where it's only possible to change data, but not schemas, permissions and so on in a production environment. Could be enabled by an environment variable or something similar outside the application. This would make sure a production environment is predictable. |
Beta Was this translation helpful? Give feedback.
-
I don't know if it's been suggested yet, but I would love to be able to define my models/tables as Database Markup Language (DBML) files and then have Directus figure out the required migrations based on them. I love the idea of being able to write docs as code which generates the database at the same time. Plus automated typing and voila! Everything is always in sync. I think DBML is also arguably a bit more accessible for non-traditional developers. Great for those who want a way to define their data schema as code even if they're not particularly fluent in Typescript (or any language for that matter) Could also be used in the Directus App to visualise the relationships as well |
Beta Was this translation helpful? Give feedback.
-
Want to share an experimental tool for a code-first configuration of Directus within a Nuxt app. Maybe some of the ideas in it can be interesting for the discussion here :) The repo is here: https://github.com/jofmi/directus-nuxt-migrations I like this approach because it lets you declare modular database schemas within a Nuxt app and migrate them to Directus via the SDK. This makes it possible to write Nuxt modules that include frontend code, custom API endpoints, and the Directus database structure in one publishable package - similar to how I was used to it in Django. Another idea that I had was whether it is possible to write something like a Drizzle ORM adapter for Directus. |
Beta Was this translation helpful? Give feedback.
-
Hi, has anyone used zenstack? i see there are a lot of things similar to directus permissions configuration but as a DSL language. Row and column level security, validation... is it possible to use zenstack in directus? |
Beta Was this translation helpful? Give feedback.
-
It would be great if schemas, roles and permissions could be managed via code. Often custom permissions contain logic that is of a fairly technical nature and should ideally be versioned and repeatable between dev/staging/prod environments.
By supporting code-first configuration, a team of developers could collaborate on things like permission logic and easily keep their local development environments in sync via source control. Ideally permissions logic could then also be unit tested.
Currently schemas, roles and permissions are configured in the UI and stored in the database. It is of course possible to create schema snapshots and export permissions and roles via the API, however this approach does not fit naturally into a DevOps flow with multiple developers and multiple environments.
The general idea is that schemas, roles and permissions could be developed in code (e.g. yaml) and applied to the database the next time directus is started. An extension of this would be that changes made via the UI (locally) are reflected back to code and can be reviewed and committed to source control. Applying changes to production could be part of a CI/CD pipeline (e.g. Github Actions) which could use the directus API.
Beta Was this translation helpful? Give feedback.
All reactions