A permissions test that checks whether an administrator sees an edit button proves very little about the rest of an application. The important question is whether every relevant request enforces the intended access rule, including requests made outside the visible interface.
Build a permission matrix around people, actions and records. Then test both allowed and refused operations in an authorised test environment. This turns a broad requirement such as “role-based access” into evidence that a product owner can review.
Write the policy before writing tests
Describe who should do what in business language. Separate reading, creating, editing, approving, exporting and deleting. A person allowed to read a request may not be allowed to download every attachment or change its owner.
Include record relationships and organisational boundaries. A role name alone rarely explains the full rule. “Coordinator” might mean access to one team, one customer account or all operations. Resolve that ambiguity with the responsible business owner before treating any result as correct.
OWASP's Authorization Cheat Sheet recommends least privilege, denial by default and permission checks on every request. It also recommends tests for the intended rules. These principles support the method here; the actual policy must come from your application's requirements.
Choose representative identities and records
Hypothetical example: a maintenance portal has technicians, coordinators and customer viewers. Technicians update assigned jobs. Coordinators manage jobs for their own organisation. Customer viewers read approved reports for their own sites. None of these descriptions automatically grants access to another organisation.
Create test accounts for each role, including two users with the same role in different organisations. Add an inactive account, an unauthenticated session and a user whose assignment changes. Use fabricated records with clear labels so unexpected access is easy to recognise.
Prepare records in relevant states: draft, assigned, completed and archived. Permissions may change with state, so testing only a fresh record misses important rules. Include an attachment and an exportable record where the application supports them.
Construct the matrix around decisions
Each test row should identify the actor, action, target, context and expected result. Include a short business reason. A matrix of role names and ticks can be a useful summary, but the executable cases need enough detail to remove guesswork.
| Actor | Attempt | Expected decision |
|---|---|---|
| Assigned technician | Update own active job | Allow permitted fields |
| Other technician | Update the same job | Deny |
| Coordinator | Export another organisation's jobs | Deny |
| Customer viewer | Read an unpublished report | Deny |
| Inactive user | Reuse a previously valid session | Enforce the agreed revocation rule |
Do not infer edit permission from read permission. Test sensitive fields separately, including role assignment, organisation identifiers and approval status. An otherwise permitted update should not allow a user to alter fields outside their authority.
Exercise the server-facing paths
Test the normal interface first, then verify the underlying requests with the same test identity. Hiding a control improves usability but does not establish enforcement. Direct record addresses, API endpoints and background actions all need the relevant checks.
For a refused change, inspect the stored record afterwards. A denial message is misleading if part of the update already occurred. Check related effects too: notifications, queued work and generated files should not appear as a consequence of an unauthorised action.
Review list and search results as well as individual records. Titles, counts and autocomplete suggestions can reveal information across account boundaries. Test exports and attachment downloads separately, since they may use different code paths from the main page.
Test permission changes during active work
Open an editable record, then change the user's role or assignment through an authorised administrator. Submit the older form and verify the current policy is applied. Decide how the interface explains that the user's access changed.
Include queued jobs and delayed exports. A user may have permission when requesting an export but lose it before the file is generated or downloaded. Define the required checks at each stage rather than relying on a single decision at the start.
Where temporary access is supported, test its expiry and removal. Record the expected revocation timing for sessions and tokens. Avoid claiming immediate revocation unless the implementation and tests demonstrate that behaviour.
Keep failures reproducible and contained
For each result, record the application version, test identity, relevant policy, target record and observed outcome. Store evidence without passwords, session tokens or unnecessary personal information. Use screenshots only when they explain something the request and result cannot.
When a test fails, identify whether the policy is unclear or the implementation violates an agreed rule. Resolve uncertainty with the product owner, then update the matrix. Do not quietly change the expected result merely to make the test pass.
Automate stable cases that protect important boundaries and rerun them when access logic changes. Keep exploratory review for new workflows and unusual combinations. A passing matrix supports the tested boundaries; it is not proof that every security concern has been addressed.
Apply these checks to the B2B account and quote approval workflow. For implementation discussions, see Visuosofts' application development service and contact the team with your roles, record boundaries and sensitive actions.