SharePoint  

Automating SharePoint Permissions with PnPjs

Managing permissions effectively in SharePoint often requires breaking away from inherited security and applying custom rules at the item or library level. In this article, we’ll explore how to break permission inheritance, grant unique permissions, restore inheritance, and apply advanced item-level security — all using the modern PnPjs (spfi) approach in SPFx.

This continues our PnPjs SPFx series, following the article on Custom Role Definitions & Dynamic Permission Assignment.

Why Break Permission Inheritance?

By default, SharePoint lists, libraries, and items inherit permissions from their parent site or list. However, business requirements often demand unique access, such as:

  • Restricting access to sensitive documents.
  • Assigning unique reviewers to a single record.
  • Granting temporary permissions for project-specific tasks.

1. Setting up PnPjs in SPFx

Make sure you have PnPjs configured as per our initial setup guide.

npm install @pnp/sp @pnp/graph @pnp/logging @pnp/queryable

Example setup (spfxPnPSetup.ts):

2. Break Permission Inheritance

import "@pnp/sp/items";

const breakItemInheritance = async (context: WebPartContext, listTitle: string, itemId: number) => {
  const sp = getSP(context);
  await sp.web.lists.getByTitle(listTitle).items.getById(itemId).breakRoleInheritance(false); 
  console.log(`Permission inheritance broken for item ${itemId}`);
};

Parameters

  • false → clears existing permissions, starting fresh.
  • true → keeps existing permissions and allows custom additions.

3. Grant Unique Permissions to a User

import "@pnp/sp/security";
import "@pnp/sp/site-users";

const grantItemPermission = async (context: WebPartContext, listTitle: string, itemId: number, userEmail: string, roleName: string) => {
  const sp = getSP(context);
  
  const user = await sp.web.ensureUser(userEmail);
  const roleDef = await sp.web.roleDefinitions.getByName(roleName)();

  await sp.web.lists.getByTitle(listTitle).items.getById(itemId)
    .roleAssignments.add(user.data.Id, roleDef.Id);

  console.log(`Granted ${roleName} permission to ${userEmail} on item ${itemId}`);
};

4. Restore Inheritance

const restoreItemInheritance = async (context: WebPartContext, listTitle: string, itemId: number) => {
  const sp = getSP(context);
  await sp.web.lists.getByTitle(listTitle).items.getById(itemId).resetRoleInheritance();
  console.log(`Inheritance restored for item ${itemId}`);
};

5. Best Practices for Item-Level Security

  • Minimize Broken Inheritance: Too many unique permissions can degrade performance.
  • Use Groups Over Direct Assignments: Assign permissions to SharePoint groups rather than individual users.
  • Document Security Changes: Keep logs for auditing.
  • Test in a Non-Production Site: Permissions changes are immediate and can block user access.

Conclusion

By mastering breaking and restoring permission inheritance with PnPjs, you gain fine-grained control over SharePoint security. This approach is essential for scenarios involving sensitive data, project-specific content, or custom workflows.

In our next blog, we’ll explore batch permission updates, large-scale security audits, and automated permission cleanup using PnPjs.