Making Sitecore Content Security Seamless in Headless Architectures
When moving from MVC-based Sitecore solutions to headless architecture like Next.js, one critical aspect is content security. Fortunately, Sitecore's out-of-the-box item security can be extended to work with headless applications.
This post will walk you through why leveraging Sitecore’s built-in security is advantageous, and how you can extend Sitecore to expose security metadata for headless consumption.
Why Use Sitecore's Out-of-the-Box Item Security?
Inheritance Is Handled Automatically
Sitecore’s item security naturally supports inheritance.
Reuse Existing Security Rules During Migration
When migrating from MVC to Headless, you can keep the existing security definitions in your content tree without additional work.
How to Extend Sitecore for Headless Item Security
To expose page level security metadata to your headless app (like in a Next.js front-end), you need to extend the Sitecore CM instance by attaching event handlers that update custom fields based on item security.
Add Access Control Fields to Page Templates
Add an Access Control section to your page templates with three new fields:
accessControlSecured
(Boolean) — a toggle to determine whether the item is public or secured.accessControlAllowed
(Multline-Text) — roles allowed to read a page.accessControlDenied
(Multline-Text) — roles denied to read a page.
Attach Event Handlers
Attach handlers to these events:
OnItemAdded
OnItemMoved
OnItemSaved
//Shows how to verify which fields are changing, this prevents an infinite loop of updates.
var changes = ((ItemChanges)((SitecoreEventArgs)args).Parameters[1]).FieldChanges;
bool securityFieldChanged = changes.Contains(Sitecore.FieldIDs.Security);
Extracting the Item from the Event
//Use ExtractParameter to get the affected item in the Event Handler
var item = Event.ExtractParameter(args, 0) as Item;
Evaluate and Update Access Control Metadata
Apply the following to the item and all its descendants:
Anonymous Role
Always get the Anonymous
role for public/private evaluation.
bool isSecured = AuthorizationManager.GetAccess(item, anonymousRole, AccessRight.ItemRead).Permission != AccessPermission.Allow;
Update accessControlSecured
based on the evaluation.
Retrieve Roles from Context Item and All Its Parents
Get all roles present in the __Security
field, process only the relevant page-level roles (filter by domain or naming patterns if necessary).
The __Security
field is a multi-line text with roles, user names, and access rights all together. Use a text extraction method to get only the roles.
Collect the roles from the item and all its parents.
Get all present roles in all parent items.
Check Specific Role Access One by One
foreach (var role in allRoles)
{
if (AuthorizationManager.GetAccess(item, role, AccessRight.ItemRead).Permission == AccessPermission.Allow)
canReadRoles.Add(role);
}
foreach (var role in allRoles)
{
if (AuthorizationManager.GetAccess(item, role, AccessRight.ItemRead).Permission == AccessPermission.Deny)
deniedRoles.Add(role);
}
Populate accessControlAllowed
and accessControlDenied
fields accordingly.
Repeat for All Descendants
Process all subitems to ensure security inheritance is respected.
When the __Security
field changes, or an item is moved, all its descendants will be affected. Repeating the evaluation process updating the access control fields is necessary.
Update access control in all descendants
Using the Access Control Fields in the Head App
Now, with all the fields properly set, you can easily determine access in the head application.
For example, in a Next.js application using SSG (Static Site Generation), a middleware plugin can read the accessControlSecured
, accessControlAllowed
, and accessControlDenied
fields to perform access evaluations at runtime.
Performance Considerations
Works great for manually curated content trees and reasonable role counts.
Final Thoughts
Leveraging Sitecore's native item security for headless apps saves time, preserves existing definitions, and simplifies future maintenance.
By extending the CM instance with event handlers, you expose security metadata without rebuilding complex permission systems.