Files
directus/docs/use-cases/headless-cms/security.md
Bryant Gillespie e3f688acb2 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>
2023-04-06 15:21:00 -04:00

125 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.
![The custom permissions interface for the Public role is displayed. The Item Permissions table is active and one Rule is active - "Status" Equals "Published".](https://cdn.directus.io/docs/v9/headless-cms/security-20230322/custom-permissions.webp)
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, theres 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 dont 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 its 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).
![The Administrator role settings page is displayed. The Require 2FA form field is highlighted and enabled.](https://cdn.directus.io/docs/v9/headless-cms/security-20230322/2fa-role.webp)
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.
![A sample user's detail page is shown. The Two-Factor Authentication form field is highlighted. ](https://cdn.directus.io/docs/v9/headless-cms/security-20230322/2fa-user.webp)
2. **Enable the Strong option for Auth Password Policy under
[Project Settings > Security](/configuration/project-settings#security).**
![The Project Settings page is shown. The Security section is highlighted. Within the Security, section there are two fields shown: Auth Password Policy and Auth Login Attempts.](https://cdn.directus.io/docs/v9/headless-cms/security-20230322/security-project-settings.webp)