SilverStripe uses Groups and Permissions to control CMS access. This guide explains how to configure roles and manage what users can do.
Understanding SilverStripe Permissions
SilverStripe access control uses:
- Groups: Collections of users with shared permissions
- Permissions: Specific capabilities (e.g., "Edit Page", "Delete Member")
- Roles: Pre-configured permission sets within groups
Default Permission Groups
Administrators
Full access to:
Create: Automatically created during installation
Content Authors
Can:
- Edit pages
- Upload files
- Create content
Cannot:
- Access Settings
- Manage users
- Delete published pages
Creating Custom Groups
Via CMS
- Security > Groups
- Click Add Group
- Enter Title (e.g., "Marketing Team")
- Go to Permissions tab
- Select permissions
- Save
Via PHP
File: app/src/Tasks/CreateGroupTask.php
<?php
namespace App\Tasks;
use SilverStripe\Dev\BuildTask;
use SilverStripe\Security\Group;
use SilverStripe\Security\Permission;
class CreateGroupTask extends BuildTask
{
protected $title = 'Create Custom Group';
public function run($request)
{
$group = Group::create();
$group->Title = 'Marketing Team';
$group->Code = 'marketing-team';
$group->write();
// Grant specific permissions
Permission::grant($group->ID, 'CMS_ACCESS_CMSMain');
Permission::grant($group->ID, 'FILE_EDIT_ALL');
echo "Group created: {$group->Title}\n";
}
}
Common Permissions
CMS Access
CMS_ACCESS_CMSMain- Access Pages sectionCMS_ACCESS_AssetAdmin- Access Files sectionCMS_ACCESS_SecurityAdmin- Access Security sectionCMS_ACCESS_LeftAndMain- Basic CMS access
Page Permissions
EDIT_CONTENT- Edit page contentEDIT_PERMISSIONS- Change page permissionsVIEW_DRAFT_CONTENT- View draft pagesPUBLISH_PAGES- Publish pages
File Permissions
FILE_EDIT_ALL- Edit all filesFILE_DELETE_ALL- Delete files
Page-Level Permissions
Set Who Can Edit Pages
In CMS:
- Edit a page
- Go to Settings tab
- Who can edit this page?
- Select groups or users
- Save
Via Code
File: app/src/Page.php
<?php
namespace {
use SilverStripe\CMS\Model\SiteTree;
class Page extends SiteTree
{
public function canEdit($member = null)
{
// Custom logic
if ($member && $member->inGroup('marketing-team')) {
return true;
}
return parent::canEdit($member);
}
public function canPublish($member = null)
{
// Only admins can publish
return Permission::checkMember($member, 'ADMIN');
}
}
}
DataObject Permissions
Control who can manage custom data objects:
File: app/src/Models/BlogPost.php
<?php
namespace App\Models;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Permission;
class BlogPost extends DataObject
{
private static $table_name = 'BlogPost';
public function canView($member = null)
{
return true; // Public
}
public function canEdit($member = null)
{
// Only editors and admins
return Permission::checkMember($member, ['ADMIN', 'BLOG_EDITOR']);
}
public function canDelete($member = null)
{
// Only admins
return Permission::checkMember($member, 'ADMIN');
}
public function canCreate($member = null, $context = [])
{
return Permission::checkMember($member, ['ADMIN', 'BLOG_EDITOR']);
}
}
Custom Permissions
Define Custom Permission
File: app/src/Extensions/CustomPermissions.php
<?php
namespace App\Extensions;
use SilverStripe\Security\PermissionProvider;
class CustomPermissions implements PermissionProvider
{
public function providePermissions()
{
return [
'BLOG_EDITOR' => [
'name' => 'Edit Blog Posts',
'category' => 'Blog permissions',
],
'BLOG_PUBLISHER' => [
'name' => 'Publish Blog Posts',
'category' => 'Blog permissions',
],
];
}
}
Register:
SilverStripe\Security\Security:
extensions:
- App\Extensions\CustomPermissions
Grant Custom Permission
Permission::grant($groupID, 'BLOG_EDITOR');
Role-Based Access
Configure Roles in Groups
Via CMS:
- Security > Groups
- Select group
- Roles tab
- Create role with permission set
- Apply role
Roles vs Permissions
- Roles: Bundled permission sets (e.g., "Content Author" role)
- Permissions: Individual capabilities
Permission Comparison Table
| Capability | Admin | Content Author | Marketing | Member |
|---|---|---|---|---|
| View CMS | ||||
| Edit pages | ||||
| Publish pages | ||||
| Manage users | ||||
| Access settings | ||||
| Upload files |
Testing Permissions
Test as Different User
- Create test user
- Add to specific group
- Log in as that user
- Verify access is correct
Code Testing
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
$member = Member::get()->filter('Email', 'test@example.com')->first();
// Check permission
if (Permission::checkMember($member, 'BLOG_EDITOR')) {
echo "Has permission";
}
Best Practices
1. Principle of Least Privilege
Give users minimum access needed:
// Good - Specific permissions
Permission::grant($group->ID, 'CMS_ACCESS_CMSMain');
// Bad - Too broad
Permission::grant($group->ID, 'ADMIN');
2. Use Groups, Not Individual Permissions
Assign users to groups rather than individual permissions.
3. Regular Audits
Review group memberships quarterly.
Troubleshooting
User Can't Access CMS
Check:
- User is in a group with CMS permissions
- Group has
CMS_ACCESS_LeftAndMainpermission - User is active
User Can Edit But Not Publish
Solution: Grant PUBLISH_PAGES permission to their group.