Keep permission checks at the boundary
Use the request context when checking access to data and actions. A hidden button is not an authorization check: callers can invoke a model or endpoint directly.
Check the resource, action, and module permission that the operation requires. Return a clear error when access is denied. Test as an anonymous visitor, an editor with limited rights, and an administrator.
Avoid replacing the caller's context with a privileged shell context in application code. If a background task needs elevated access, constrain the operation and authorize its initiation explicitly.
Test with different users
Choose roles that exercise the operation's permission boundary: anonymous visitor, limited editor, and administrator. Use separate browser sessions or an explicit test context for each role.
Test the direct model or endpoint as well as the visible interface. Confirm that denied writes leave the data unchanged and do not reveal private fields in the error response.
Include unpublished resources and resources outside the user's content group where relevant. Record the role and resource used in the test so someone else can reproduce the result.