diff --git a/src/Umbraco.Core/Services/ContentPermissionManager.cs b/src/Umbraco.Core/Services/ContentPermissionManager.cs
new file mode 100644
index 0000000000..ad6fe0ee5c
--- /dev/null
+++ b/src/Umbraco.Core/Services/ContentPermissionManager.cs
@@ -0,0 +1,117 @@
+// src/Umbraco.Core/Services/ContentPermissionManager.cs
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Models.Entities;
+using Umbraco.Cms.Core.Models.Membership;
+using Umbraco.Cms.Core.Persistence.Repositories;
+using Umbraco.Cms.Core.Scoping;
+
+namespace Umbraco.Cms.Core.Services;
+
+///
+/// Internal manager for content permission operations.
+///
+///
+///
+/// This is an internal class that encapsulates permission operations extracted from ContentService
+/// as part of the ContentService refactoring initiative (Phase 6).
+///
+///
+/// Design Decision: This class is internal (not public interface) because:
+///
+/// - Permission operations are tightly coupled to content entities
+/// - They don't require independent testability beyond ContentService tests
+/// - The public API remains through IContentService for backward compatibility
+///
+///
+///
+/// Note: GetPermissionsForEntity returns EntityPermissionCollection which is a
+/// materialized collection (not deferred), so scope disposal before enumeration is safe.
+///
+///
+internal sealed class ContentPermissionManager
+{
+ private readonly ICoreScopeProvider _scopeProvider;
+ private readonly IDocumentRepository _documentRepository;
+ private readonly ILogger _logger;
+
+ public ContentPermissionManager(
+ ICoreScopeProvider scopeProvider,
+ IDocumentRepository documentRepository,
+ ILoggerFactory loggerFactory)
+ {
+ // v1.1: Use ArgumentNullException.ThrowIfNull for consistency with codebase patterns
+ ArgumentNullException.ThrowIfNull(scopeProvider);
+ ArgumentNullException.ThrowIfNull(documentRepository);
+ ArgumentNullException.ThrowIfNull(loggerFactory);
+
+ _scopeProvider = scopeProvider;
+ _documentRepository = documentRepository;
+ _logger = loggerFactory.CreateLogger();
+ }
+
+ ///
+ /// Used to bulk update the permissions set for a content item. This will replace all permissions
+ /// assigned to an entity with a list of user id & permission pairs.
+ ///
+ /// The permission set to assign.
+ public void SetPermissions(EntityPermissionSet permissionSet)
+ {
+ // v1.1: Add input validation
+ ArgumentNullException.ThrowIfNull(permissionSet);
+
+ // v1.1: Add logging for security-relevant operations
+ _logger.LogDebug("Replacing all permissions for entity {EntityId}", permissionSet.EntityId);
+
+ using ICoreScope scope = _scopeProvider.CreateCoreScope();
+ scope.WriteLock(Constants.Locks.ContentTree);
+ _documentRepository.ReplaceContentPermissions(permissionSet);
+ scope.Complete();
+ }
+
+ ///
+ /// Assigns a single permission to the current content item for the specified group ids.
+ ///
+ /// The content entity.
+ /// The permission character (e.g., "F" for Browse, "U" for Update).
+ /// The user group IDs to assign the permission to.
+ public void SetPermission(IContent entity, string permission, IEnumerable groupIds)
+ {
+ // v1.1: Add input validation
+ ArgumentNullException.ThrowIfNull(entity);
+ ArgumentException.ThrowIfNullOrWhiteSpace(permission);
+ ArgumentNullException.ThrowIfNull(groupIds);
+
+ // v1.2: Add warning for non-standard permission codes (Umbraco uses single characters)
+ if (permission.Length != 1)
+ {
+ _logger.LogWarning(
+ "Permission code {Permission} has length {Length}; expected single character for entity {EntityId}",
+ permission, permission.Length, entity.Id);
+ }
+
+ // v1.1: Add logging for security-relevant operations
+ _logger.LogDebug("Assigning permission {Permission} to groups for entity {EntityId}",
+ permission, entity.Id);
+
+ using ICoreScope scope = _scopeProvider.CreateCoreScope();
+ scope.WriteLock(Constants.Locks.ContentTree);
+ _documentRepository.AssignEntityPermission(entity, permission, groupIds);
+ scope.Complete();
+ }
+
+ ///
+ /// Returns implicit/inherited permissions assigned to the content item for all user groups.
+ ///
+ /// The content item to get permissions for.
+ /// Collection of entity permissions (materialized, not deferred).
+ public EntityPermissionCollection GetPermissions(IContent content)
+ {
+ // v1.1: Add input validation
+ ArgumentNullException.ThrowIfNull(content);
+
+ using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
+ scope.ReadLock(Constants.Locks.ContentTree);
+ return _documentRepository.GetPermissionsForEntity(content.Id);
+ }
+}