Sections, roles and policies
This page is for developers who decide who may read and change what. Exponential's access control is part of the content model: rules are written against classes, sections, subtrees and states, so a good model makes the rules short, and the rules are checked by every fetch, view and API call without your code doing anything.
Contents
- Roles, policies and limitations
- The content policies you use most
- Limitations
- Assigning roles
- Sections: the main lever
- Object states: stages with their own rules
- Access in templates
- Checking and debugging access
- Designs that work
Roles, policies and limitations
| Piece | Is | Example |
|---|---|---|
| Policy | permission for one module and one function (or all) | content/read, content/create, user/login |
| Limitation | a condition on a policy | Class = Article; Section = Members |
| Role | a named set of policies | Editor, Member, Anonymous |
| Assignment | a role given to a user or a user group, optionally limited to a subtree or a section | Editor to the group News team, on the subtree News |
Permissions only add up: there is no "deny" policy. A user may do something when any of their roles has a policy that allows it. Roles are managed under Users > Roles and policies (Roles, policies and unactivated users).
The content policies you use most
The functions of the content module (kernel/content/module.php) include:
| Function | Allows |
|---|---|
read | seeing content: views, fetches, search results, the REST interface |
create | creating objects of a class below a parent |
edit | creating new versions of existing objects |
publish | publishing a draft |
remove, move, hide, manage_locations | changing the tree |
translate | working on translations |
versionread, versionremove, diff | reading and removing old versions, comparing them |
view_embed | showing an object embedded in other content without full read access |
pdf, bookmark, dashboard, restore, cleantrash, jobs | the named features |
Other modules have their own functions: user/login (signing in to a siteaccess), user/selfedit, setup/*,
apikey/create and so on. Your own modules declare theirs
(Policy functions and access).
Limitations
The limitations of content functions are Class, Section, Owner, Group, Node, Subtree, Language, the
parent-side ParentClass, ParentOwner, ParentGroup, Status for versions, and one limitation per object state
group. Within a policy all limitations must match; across policies any one may allow.
| Need | Policy |
|---|---|
| Editors create articles in News only | content/create with Class = Article and Subtree = News (or Node = the News folder) |
| Authors change only their own items | content/edit with Owner = self |
| A translator works only in German | content/edit and content/translate with Language = German |
| Reviewers edit only items in review | content/edit with the state limitation of your review group = In review |
Assigning roles
Assign roles to user groups, not to single users, so a new team member gets the right access by being placed in the group. An assignment can itself be limited to a subtree or a section, so one Editor role serves several departments, each assigned to its own subtree. Users are content in groups: Users and registration.
Sections: the main lever
A section is one label per object. A new installation has five (Standard, Users, Media, Setup, Design), and the
Anonymous role reads only Standard: that single limitation keeps user accounts and other sections from visitors
(Sections, section 2). For a members area, create a
section Members, assign the subtree to it, and give a Member role content/read limited to that section. New
content takes the section of its parent. Sections also select templates (Match[section] in override rules) and
navigation parts in the administration (Sections).
Object states: stages with their own rules
Object states are labels of your own in groups (for example Review: draft, in review, approved). Policies can be limited by state, and states change by hand, from workflows or from code. Use them for editorial stages that need different rights; use sections for areas of the site (Object states).
Access in templates
Fetches and views already leave out what the user may not read. For buttons and links, ask the node:
if $node.can_edit
<a href=concat( 'content/edit/', $node.contentobject_id )|ezurl>'Edit'|i18n( 'extension/exp_mysite' )</a>
/ifNodes answer can_read, can_create, can_edit, can_hide, can_remove, can_move and more
(Node attributes reference). The operators has_role,
has_policy and their variants ask about the user instead
(Role and policy template operators). Never use them to
hide content that the user may read anyway: that is design, not security.
Checking and debugging access
./console exp:accesscheck --helpanswers what a user may do with a node or object and which limitation refuses it
(Sections, roles and access for builders).
Test with a dedicated test account (address at example.invalid), never by trying things as an administrator.
Designs that work
- Few roles, many assignments. One Editor role assigned per subtree beats one role per department.
- Sections for audiences, states for stages, classes for kinds of content. Do not encode one in another.
- Least privilege. Start from nothing and add; an import user gets exactly the create and edit rights it needs.
- Keep the Anonymous role small.
content/readon Standard,user/loginon the public siteaccess, and only what the site's forms need.
Related pages
- Sections: every page of the section administration
- Security checklist
- eZUser and access
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.