Netlify CMS (now Decap CMS) takes a fundamentally different approach to user management than traditional CMSes. There is no database-backed user table. Instead, authentication is delegated to an identity provider -- most commonly Netlify Identity or a custom OAuth backend -- and the CMS itself acts as a Git-based editing interface. Permissions are coarse by design, and fine-grained access control happens at the Git and identity layer rather than inside the CMS admin panel.
Permission model
Netlify CMS operates on two permission layers:
- Identity provider roles -- Netlify Identity assigns each user a
rolearray stored in JWT claims. The CMS config maps these roles to editorial capabilities. Without Netlify Identity, you use an external OAuth provider (GitHub, GitLab, Bitbucket) and permissions follow repository access. - Editorial Workflow states -- when
publish_mode: editorial_workflowis enabled inconfig.yml, content moves through Draft, In Review, and Ready states. Any authenticated user can create drafts, but publishing (merging the PR) requires a user whose Git credentials have write/merge access to the target branch.
There are no per-field, per-collection, or per-folder permissions in the CMS itself. If a user can log in, they can see and edit all collections defined in config.yml.
Built-in roles
Netlify Identity supports arbitrary role strings. Common patterns:
| Role string | Typical usage | Controlled by |
|---|---|---|
admin |
Full CMS access, can invite other users | Netlify Identity dashboard or Admin API |
editor |
Content editing, no user management | Netlify Identity role assignment |
reviewer |
View drafts in editorial workflow | Custom middleware or branch protection rules |
| (no role) | Default authenticated user | Can edit all collections unless filtered by config.yml |
Roles are set in the Netlify Identity dashboard under Identity > User management > [User] > Metadata > app_metadata.roles. They appear as ["admin", "editor"] in the JWT.
To restrict CMS access to only certain roles, add to config.yml:
backend:
name: git-gateway
branch: main
# Only allow users with these roles
allowed_roles:
- admin
- editor
Admin UI paths
| Task | Location |
|---|---|
| Manage Identity users | Netlify Dashboard > Site > Identity |
| Invite new users | Identity > Invite users (email-based) |
| Set user roles | Identity > [User] > Edit > app_metadata |
| Enable Git Gateway | Identity > Services > Git Gateway > Enable |
| Configure CMS collections | admin/config.yml in repository |
| Enable editorial workflow | publish_mode: editorial_workflow in config.yml |
| External OAuth setup | Identity > Registration > External providers |
API access management
Netlify Identity API:
- REST endpoints at
https://<site>.netlify.app/.netlify/identity/ - Invite users:
POST /.netlify/identity/invitewith admin JWT - List users:
GET /.netlify/identity/admin/users(requires admin token) - Update roles:
PUT /.netlify/identity/admin/users/<id>withapp_metadata.roles
Git Gateway:
- Proxies Git operations through Netlify, so CMS users never need direct repo credentials
- Uses the Identity JWT to authorize; the gateway itself holds a repo access token
- Token stored in Netlify's backend -- rotate by disabling/re-enabling Git Gateway
GoTrue (self-hosted Identity):
- If running Decap CMS outside Netlify, GoTrue handles auth
- Admin API at
/admin/userswith service-role key - Roles stored in
app_metadataidentical to Netlify Identity
Analytics-specific permissions
Since Netlify CMS is a Git-based editor, analytics configurations are typically files in the repository:
- GTM/GA config files -- if you store tag configuration in JSON or YAML files editable via the CMS, any authenticated user can modify them. Protect analytics collections by moving them to a separate branch or repo that requires PR approval.
- Head injection -- analytics scripts in
<head>are usually in layout templates (e.g.,_includes/head.html), which are code files not exposed through the CMS UI. This provides natural isolation. - Netlify Analytics (separate product) -- managed entirely in the Netlify Dashboard under Analytics. Access follows Netlify team membership, not CMS roles. Team members with Owner or Developer roles can view analytics; Collaborators cannot.
- Build-time analytics plugins -- plugins like
gatsby-plugin-google-gtagare configured ingatsby-config.jsor equivalent. Changes require a code commit, enforced by branch protection.
For analytics governance, keep tracking code in template files outside CMS-editable collections, and use branch protection rules to require reviews on merges that touch analytics-related paths.
Sub-pages
- Roles and Permissions -- Netlify Identity role configuration, JWT claims, and editorial workflow permission mapping
- Adding and Removing Users -- inviting users via Identity dashboard, managing Git Gateway access, and offboarding