Skip to main content

Introduction to the Policy Based Access Checking in Drupal 10

Traditionally, access control in Drupal was primarily 'role-based.' The site owner would define various roles and assign specific permissions to each. These roles would then be assigned to users. If a user’s role included the necessary permission to perform a certain task, access would be granted; otherwise, it would be denied.

Access control in Drupal

Despite being simple and straightforward, this way of access checking had a lot of limitations.

The  Policy Based Access Checking was introduced in Drupal 10.3 to overcome such limitations of the traditional access control.

How it works

Policy Based access control

The Access Policy API is the core of the Policy Based Access Checking(PBAC).Access policy is a tagged service that can add or remove permissions for a particular user, based on globally available context data such as the domain, time of day, current user's field values, etc. So, to create an access policy, create a service that extends the class \Drupal\Core\Session\AccessPolicyBase, and then add the ‘access_policy’ tag to the service.

The access policy calculates the permissions in 2 phases: The Build phase and the Alter phase.

Build phase

The following example illustrates the build phase of an access policy that gives additional permissions to the user based on the user’s timezone.

The calculatePermissions() method returns an object of type RefinableCalculatedPermissionsInterface. Since the access varies based on the user’s timezone, the getPersistentCacheContexts() method returns the ‘timezone’ context.

Alter phase

The following example illustrates how to revoke certain permissions from a user based on the user’s email domain, during the ‘alter’ phase.

This policy checks the email domain of  the user and grants only authenticated user permissions, if the email domain is ‘example.com’. Note that the ‘overwrite’ parameter is set to ‘FALSE’ to fully change the permissions. The getPersistentCacheContexts() returns a custom cache context that depends on the user’s email domain.

Scopes and identifiers

Both ‘Scopes’ and ‘Identifiers’ help to increase the specificity of access policies.

Consider a simple scenario where the user should have access only to the ‘English’ translations of ‘Recipe’ contents. The scope can be defined as ‘recipe’ and the identifier as ‘en’.

The applies() method ensures that the above access policy is only applicable in the ‘recipe’ scope. The ‘scope’ and ‘identifier’ values are also passed along with the permissions to edit and create ‘recipe’ contents. This policy can be then invoked in the following way.

In this way, The ‘edit any recipe content’ permission would be available only if the node’s language is ‘en’ so that non English recipe contents won’t be editable by the user.

Conclusion

The new access policy is definitely a worthy addition to the ever-evolving Drupal core. It’s more robust and efficient than the existing systems, and I hope this blog has given you a better understanding of it. Here is a quick summary of all topics explored in this blog.

The code used in this blog can be found at: Github Link

We'd love to talk about your business objectives

Written by