mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Security in Headless CMS Guide (#18073)
* migrate from docs repo * sign cla agreement * Remove .gitignore in docs in favor of root file * content updates * ignore vitepress cache * add 2FA to dictionary --------- Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -29,4 +29,4 @@ debug.ts
|
||||
.thumbsmith
|
||||
.netlify
|
||||
.gitpod.yml
|
||||
.vitepress/cache
|
||||
*/.vitepress/cache
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
- Romakita
|
||||
- br41nslug
|
||||
- licitdev
|
||||
- bryantgillespie
|
||||
|
||||
@@ -500,6 +500,10 @@ function sidebar() {
|
||||
text: 'Create Re-Usable Page Components',
|
||||
link: '/use-cases/headless-cms/create-reusable-page-components-using-m2a',
|
||||
},
|
||||
{
|
||||
text: 'Security Best Practices',
|
||||
link: '/use-cases/headless-cms/security',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
(R|r)elink
|
||||
(R|r)epo
|
||||
(R|r)ollup
|
||||
(S|s)erverless
|
||||
(S|s)chemas?
|
||||
(S|s)endmail
|
||||
(S|s)lugify
|
||||
@@ -70,6 +71,7 @@
|
||||
[0-9]*x[0-9]*
|
||||
[0-9]*x[0-9]*px
|
||||
[M|m]onorepo
|
||||
2FA
|
||||
45K
|
||||
ACL
|
||||
ACS
|
||||
@@ -140,6 +142,7 @@ directus
|
||||
Directus
|
||||
directus_(.*)
|
||||
Directus.
|
||||
Directus's
|
||||
Directus-(.*)
|
||||
Dockerfile
|
||||
Dockerhub
|
||||
@@ -312,7 +315,6 @@ SemVer
|
||||
SemVer-like
|
||||
SendGrid
|
||||
SEO
|
||||
serverless
|
||||
SES
|
||||
SFC
|
||||
siloed
|
||||
|
||||
124
docs/use-cases/headless-cms/security.md
Normal file
124
docs/use-cases/headless-cms/security.md
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
description:
|
||||
This guide covers best practices for security, authentication, and permissions within the context of Headless CMS.
|
||||
tags: []
|
||||
skill_level:
|
||||
directus_version:
|
||||
author_override:
|
||||
author: Bryant Gillespie
|
||||
---
|
||||
|
||||
# Security in Headless CMS
|
||||
|
||||
> {{ $frontmatter.description }}
|
||||
|
||||
[Headless CMS](/use-cases/headless-cms/introduction) when coupled with statically-generated sites are architecture
|
||||
choices that are generally more secure than Traditional CMS because your content is separated from the presentation
|
||||
layer. Given that users don't directly interact with a server to construct a page, there is a reduced ability for
|
||||
malicious actors to attack the website. However, it is still very important that you follow good security protocols to
|
||||
keep your data protected.
|
||||
|
||||
In this guide, we'll cover some best practices for keeping your Directus Headless CMS secure.
|
||||
|
||||
## Restrict Public Role
|
||||
|
||||
Directus makes it super easy to share your content with our REST and GraphQL APIs.
|
||||
|
||||
The Public role within [Roles and Permissions](/configuration/users-roles-permissions#roles) defines what content is
|
||||
available without authentication. To be safe, all permissions are turned off by default. This means that no data is
|
||||
available via the API without providing a proper [access token](/reference/authentication#access-tokens). Your use case
|
||||
may allow all data to be public, but it may instead require restricted access.
|
||||
|
||||
**If you do want to make data public, we recommend these guidelines.**
|
||||
|
||||
- On your public role, only enable read access.
|
||||
- Consider defining a
|
||||
[Custom Permission](/configuration/users-roles-permissions/permissions#configure-custom-permissions) for read
|
||||
operations to control which items are available and which fields within those items consumers can see.
|
||||
|
||||

|
||||
|
||||
Standard read permissions grant access to ALL data within a collection which means the general public could see
|
||||
unpublished content you might not want them to see.
|
||||
|
||||
- Do not enable create, update, or delete access for collections within the Public role. This opens your instance up for
|
||||
attack from spammers and other bad actors.
|
||||
|
||||
## Create Scoped Roles For Specific Purposes
|
||||
|
||||
As a general security rule, you should only share the minimum amount of data that is needed to achieve your goal.
|
||||
|
||||
For an example website use case, you might have several different types of users and roles that need access to various
|
||||
levels of data.
|
||||
|
||||
- **Website API** - role and user for reading content from the API (pages, posts, etc) and creating form submissions.
|
||||
- **Guest Author** - restricted role where guest post authors can only update their own content.
|
||||
- **Content Manager** - non-admin role that grants full CRUD access to all collections except business analytics.
|
||||
|
||||
For each of these roles, allow access only to the collections and specific CRUD operations that each role needs to
|
||||
perform their function.
|
||||
|
||||
Our guide on [Content Approval Workflows](/cookbook/permissions/basic-workflows) is helpful for scoping roles and
|
||||
permissions.
|
||||
|
||||
## Obscure Access Tokens and URLs
|
||||
|
||||
There are two ways to authenticate with Directus –
|
||||
[Temporary Tokens (JWT) or Static tokens](/reference/authentication#access-tokens).
|
||||
|
||||
Temporary tokens are generated by the login endpoint. They are short-lived and generally more secure.
|
||||
|
||||
Static tokens are set for each user and never expire. They are handy to use for server-to-server communication.
|
||||
|
||||
If you are using Static Tokens and your website or frontend is built using a static site generator (SSG) or calls your
|
||||
API on the client side, then you could be exposing your access token.
|
||||
|
||||
To obscure your Directus Access Tokens and URL:
|
||||
|
||||
1. **Never store access tokens inside your code or repository.** Use a .env file to store secrets and sensitive
|
||||
credentials like access tokens.
|
||||
|
||||
2. **Call your API from the server-side**. Frontend frameworks like Next.js and Nuxt.js have "server" routes that you
|
||||
can setup that are only called from the server, never on the client.
|
||||
|
||||
You can also use serverless functions or backend proxies to hide them from public view. Some website deployment
|
||||
platforms include serverless functions as part of their offering.
|
||||
|
||||
- [Vercel Serverless Functions](https://vercel.com/docs/concepts/functions/serverless-functions)
|
||||
- [Netlify Functions](https://docs.netlify.com/functions/overview/)
|
||||
|
||||
## Be Careful When Granting Admin Access
|
||||
|
||||
In a typical Directus project, there’s only a small group of people that truly need the Administrator role. The
|
||||
Administrator role provides full-access to CRUD+S Operations on every collection and rights to change any project
|
||||
settings, roles, data models, etc.
|
||||
|
||||
When granting Admin access, make sure that it is only provided to those individuals who require it to perform their job
|
||||
responsibilities. Too many Admins or granting Admin access to those who don’t truly need it can put the security of your
|
||||
Directus instance at risk.
|
||||
|
||||
## Require Two-Factor Authentication and Secure Passwords
|
||||
|
||||
Many data breaches can be attributed back to sharing passwords or using the same password across many different sites.
|
||||
|
||||
While in the development phase of your project, it can certainly be easier and quicker to use weak passwords for testing
|
||||
purposes.
|
||||
|
||||
But when it’s time to go to production and add all your different users, we recommend the following:
|
||||
|
||||
1. **Enable and enforce two-factor authentication.**
|
||||
|
||||
Two-factor authentication can be enforced for each specific role by checking the Require 2FA field in a
|
||||
[role's settings](/configuration/users-roles-permissions/roles#configure-role-details).
|
||||
|
||||

|
||||
|
||||
Individual users can enable two-factor authentication by checking the Two-Factor Authentication field on their own
|
||||
[user detail page](/app/user-directory#user-details-page) and confirming their password.
|
||||
|
||||

|
||||
|
||||
2. **Enable the Strong option for Auth Password Policy under
|
||||
[Project Settings > Security](/configuration/project-settings#security).**
|
||||
|
||||

|
||||
Reference in New Issue
Block a user