Core Architecture - Permissions System

The Permissions System is a core architectural layer in Drupal that defines what actions a user is allowed to perform. Permissions sit at the center of authorization and are consumed by routing, entity access, forms, controllers, and UI components.

Starting with Drupal 8, permissions became part of a unified, object oriented access framework that integrates tightly with roles, AccessResult, caching, and the service container. While permissions are often treated as configuration, they are a fundamental part of Drupal’s runtime security model.

The focus here is to understand permissions as an architectural primitive, not just how to define them.

Why the Permissions System Belongs in Core Architecture

Permissions are not just admin UI settings. They are referenced throughout Drupal’s execution path.

Drupal uses permissions to:

  • Control access to routes
  • Guard entity operations
  • Protect administrative actions
  • Drive UI visibility
  • Influence cache contexts

Permissions directly impact both security and cache correctness.

What Is a Permission

A permission is a string identifier that represents an allowed capability.

Examples:

  • access content
  • administer site configuration
  • edit any article content

Permissions themselves do not contain logic. They are evaluated by access checks in combination with user accounts and roles.

Roles and Permissions

Roles are collections of permissions.

Key points:

  • Users can have multiple roles
  • Permissions are additive
  • There is no built in deny permission

If a user has at least one role with a permission, the permission is granted.

Defining Permissions

Permissions are declared in a module’s permissions file.

Example: my_module.permissions.yml

my_module.manage_example:
  title: 'Manage example content'
  description: 'Create, edit, and delete example content'

Permissions are discovered during cache rebuild and exposed in the UI.

Dynamic Permissions

Permissions can be generated dynamically.

This is commonly used for:

  • Entity bundles
  • Custom operations
  • Scalable permission sets

Dynamic permissions are defined using a permission callback.

Permissions in Routing

Routes frequently reference permissions.

requirements:
  _permission: 'administer site configuration'

Route permissions are evaluated before controllers are executed.

Permissions in Entity Access

Entity access handlers evaluate permissions internally.

Example:

$node->access('update', $account);

The access handler checks:

  • Operation
  • Ownership
  • Permissions
  • Bundle rules

Permissions are only one input into entity access decisions.

Permissions in Forms and UI

Permissions control:

  • Menu link visibility
  • Form access
  • Button visibility
  • Administrative screens

UI visibility should always be backed by real access checks.

Permissions and AccessResult

Permissions are evaluated into AccessResult objects.

AccessResult:

  • Represents allow, deny, or neutral
  • Carries cacheability metadata

Using AccessResult ensures permission based output is cached safely.

Permissions and Caching

Permissions influence cache contexts.

Important cache contexts:

  • user.permissions
  • user.roles

Failing to vary cache by permissions can expose restricted content.

Drupal automatically applies these contexts when AccessResult is used correctly.

Permissions vs Roles vs Access Checks

Permissions:

  • Atomic capabilities

Roles:

  • Group permissions

Access checks:

  • Evaluate permissions in context

Permissions alone do not make decisions. Access checks do.

Common Mistakes

  • Hard coding role checks
  • Checking permissions manually everywhere
  • Ignoring cache contexts
  • Creating overly granular permissions
  • Using permissions for business logic

Permissions should remain stable and meaningful.

Drupal 10 and 11 Best Practices

  • Define clear, coarse grained permissions
  • Reuse permissions across routes and entities
  • Avoid role specific logic
  • Always rely on AccessResult
  • Document permission intent clearly

How the Permissions System Fits with Other Core Systems

The permissions system integrates tightly with:

  • User system
  • Access control API
  • Routing system
  • Entity API
  • Cache system

Permissions are a shared language across Drupal core.

Acquia Exam Notes and Cheat Sheet

Key points to remember:

  • Permissions are strings, not logic
  • Roles are additive
  • There is no built in deny permission
  • Permissions influence caching
  • Permissions are evaluated via AccessResult

Common exam traps:

  • Confusing roles with permissions
  • Checking roles directly instead of permissions
  • Forgetting user.permissions cache context
  • Assuming permissions alone enforce security

Quick decision guide:

  • Route protection: permission in routing.yml
  • Entity operation: entity access API
  • UI visibility: permission plus access check
  • Complex logic: access check service

If the question mentions roles vs permissions, permissions are atomic and roles are collections.

Summary

The permissions system is a core architectural layer that defines what users are allowed to do in Drupal. It works in concert with roles, access checks, routing, and caching to provide secure and predictable authorization behavior. Understanding permissions as an architectural concept is essential for building secure Drupal 10 and 11 systems and for passing Acquia certification exams.

This article prepares you for advanced topics such as dynamic permissions, custom access handlers, and permission driven caching strategies.