A role name is a useful label. It is a poor answer to a security question.
“Editor” tells you something about where a person’s permissions may have started. It does not tell you everything that person can do now. Capabilities can be changed, assigned directly to a user, mapped against a specific object, or affected by code running at request time. A REST request made with that person’s credentials may carry authority you did not expect from looking at a role list.
The better question is: Can this identity perform this action on this resource, through this entry point, right now?
Start with the action
Imagine a content editor working on a client site. “Can edit content” is too broad to test. Break it into decisions:
- Can they edit a draft they own?
- Can they edit a published post owned by someone else?
- Can they delete a page?
- Can they make the same change through the REST API?
Each question has an identity, an action, a resource and a context. WordPress provides capabilities to evaluate those decisions. For object-specific checks, the object matters: current_user_can( 'edit_post', $post_id ) asks WordPress about that post, not about an abstract role name. WordPress’s capability reference explains how these checks are mapped.
Count identities that do not look like people
The browser is only one route into WordPress. Integrations may use Application Passwords to make authenticated API requests. Custom REST endpoints can expose actions outside the screens you review every day. The credentials and endpoint permission checks deserve the same attention as human accounts.
Make a short inventory of who or what can act: users, service accounts, credentials, plugins and external systems. For each one, record its owner and why it still needs access. An identity with no clear owner is a question to resolve, even if its role looks harmless.
Apply the same test to AI agents connected to a site. If an agent can act through an integration, its practical reach depends on the credentials and permissions behind that integration. Record which actions it can trigger and who is responsible for reviewing them.
Test at the real boundary
A button hidden from the admin screen is not proof that an action is protected. For a custom REST endpoint, the permission_callback decides whether the request may proceed. WordPress recommends checking authorization there, often with current_user_can(), after authentication has established the current user.
Choose one sensitive action on your site and trace it end to end. Check the admin UI, the direct URL and the API route if one exists. Compare the result with what your team expected. If the outcomes differ, you have found a useful governance question.
A first exercise with AAM
Open AAM and review one role and one individual user who belongs to it. Compare their capabilities, then look at an action that matters to your site. Write down the expected access before testing it. That small habit turns a role list into an access review.
For a deeper explanation, read Effective permissions: why roles never tell the whole story and Understanding WordPress roles & capabilities.