InsightsAccess governanceWordPress securityAI agentsView all templates ↗

Access governance · Concept

Effective permissions: why roles never tell the whole story.

A WordPress role is only one input into an access decision. Security begins when you understand what an identity can actually do at runtime.

By Vasyl Martyniuk 8 min read Updated September 2026

Most WordPress access reviews begin with a role name: Administrator, Editor, Author or a custom role created by a plugin. That feels logical, but it answers the wrong question. A role describes where some permissions originated. It does not describe the final authority a user, integration or AI agent possesses.

The useful security question is not “Which role does this user have?” It is “Can this identity perform this action, against this resource, under these runtime conditions?”

Core principle

Access is the evaluated result of roles, direct grants, policy, context, application logic and runtime filters—not a static label stored in the database.

A role is a starting point

Roles are convenient permission containers. WordPress copies their capabilities into the user-resolution process, but that process can also include capabilities assigned directly to a user, super-admin rules, multisite conditions and filters applied by plugins or themes.

A user can have no role and still possess meaningful capabilities. The reverse is also true: a familiar role name can exist while its underlying capability set has drifted far from the WordPress default.

Three types of capabilities

For practical governance, it helps to distinguish capability behavior instead of treating every capability as the same kind of permission.

  1. Simple capabilities are evaluated as direct boolean permissions, such as manage_options.
  2. Compound capabilities require additional conditions or map to other primitive capabilities before a decision can be made.
  3. Dynamic capabilities are injected into the user object at runtime and may never be stored in the database.
Why this matters

A database export cannot prove effective access. If part of the permission model exists only at runtime, a complete audit must evaluate WordPress itself.

The decision happens at runtime

WordPress resolves access through functions such as current_user_can() and map_meta_cap(). The requested capability, target object and current context can all change the primitive permissions required for the final decision.

capability-check.php
// The object ID is part of the authorization context.
if (current_user_can('edit_post', $post_id)) // WordPress mapped the request to effective primitives.
    edit_post($post_id);

The presence of edit_post in a role definition is not what grants access. WordPress evaluates the requested post, ownership, post status and other conditions before resolving the primitive capabilities that matter.

Audit outcomes, not labels

An effective access audit should start with sensitive actions and work backward toward every identity that can perform them. For an agency website, that means reviewing at least:

  • Who can change plugins, themes and global settings?
  • Who can publish or delete content without review?
  • Which users have active Application Passwords or API credentials?
  • Which REST API routes expose privileged operations?
  • Which capabilities are introduced dynamically by plugins?

From permission management to governance

Permission management is the act of changing a setting. Access governance is the system around that act: visibility, intent, approval, policy, continuous verification and evidence.

That distinction is the foundation of The Access Revolution. External defenses remain necessary, but they cannot compensate for excessive authority already present inside the application.