Testing & Security

Build role based API tests for anonymous users and administrators

Kamruz
Kamruz
Oct 14, 2026
5 min read
Build role based API tests for anonymous users and administrators

An API can pass every administrator happy-path test while allowing anonymous reads or ordinary users to modify another account's records. Role tests need more than a successful response for each role. They need a matrix of operations, ownership, tenant context, and visible fields, with negative cases that bypass the UI.

Consider an illustrative article-management API. Public visitors can read published articles. Authors can edit their own drafts. Organization administrators can manage articles within their organization. Platform operations, if present, have separate explicit authority. These are example policies, not defaults for every application. The test suite must derive its expectations from the product's actual access rules.

Write policy as an operation matrix

List public read, draft read, create, update, publish, delete, and administrative listing. For each, name the allowed identities and ownership conditions. Include anonymous requests and authenticated users without the required role. Distinguish an organization administrator from a platform administrator rather than collapsing both into one admin label.

Record field visibility separately from operation permission. A visitor may read article content but not private editorial notes, account identifiers, or internal moderation metadata. An author may edit a draft without changing another user's ownership field. A practical artifact is a compact matrix with operation, actor, resource relation, expected status category, visible fields, and expected state change. This makes policy ambiguity visible before test generation.

Create independent synthetic identities

Use separate accounts for an author, another author, an organization administrator, and an unrelated tenant's administrator. Give them realistic but synthetic records. Do not make every test account an administrator through a shared fixture. That shortcut can make apparently broad tests exercise only one privileged path.

Keep authentication setup separate from the expected authorization outcome. A valid session establishes identity, not permission for every operation. Include an expired or revoked session if session lifetime is relevant to the route. Create resources belonging to different users and tenants with clearly distinguishable data. The test should know which relation it is exercising without relying on accidental fixture order or shared mutable state from earlier cases.

Test direct resource access

Call the detail, update, and delete endpoints with a resource identifier the actor should not control. The UI may never reveal that identifier, but the server still receives arbitrary requests. Test nested resources and batch inputs, where one allowed parent can hide an unauthorized child.

For organization-scoped operations, use tenant B's resource with tenant A's session and requested context. Assert the intended denial behavior without requiring an error message that reveals the resource's existence. Inspect database state after denied writes. A status code alone cannot prove that the handler returned before mutation. See tenant isolation design for extending the same boundary to jobs, files, and caches.

Assert response shape and private-field absence

Define the safe response contract for each audience. Check that private fields are absent, including fields nested in populated account records or relationship objects. A response can deny an action while still exposing sensitive data in a detailed error payload. Include error responses in the visibility review.

Avoid snapshots of entire records when they make private-field changes easy to approve without thought. Focus assertions on allowed content and explicit forbidden fields where the risk warrants it. Test mass assignment by submitting fields the actor cannot control, such as owner, role, publication authority, or tenant. The server should ignore or reject them according to the contract, and durable state should confirm that they did not take effect.

Exercise the real authorization path

Where possible, run route or application tests with the real permission logic and representative persistence. Mocking authorization to always return allowed proves little about role boundaries. A smaller unit suite can test permission rules, but it should be supplemented by evidence that routes actually invoke them with trusted context.

Check how session identity becomes the actor passed to the data operation. A route can have a correct permission helper and still supply a browser-controlled role. Inspect and test that conversion. Keep provider doubles around unrelated external effects so the authorization cases remain focused. Document which boundary uses real infrastructure and which is substituted. This prevents a broad integration label from hiding a mocked permission decision.

Check current permission and session state

Roles can change after login. Decide whether the application reads current permissions on each sensitive operation or uses a bounded cached policy. Test the intended revocation behavior. An account deleted or removed from an organization should not retain indefinite access merely because a session was issued earlier.

Include authorization at artifact download and background-job status endpoints when they expose protected data. A successful creation test does not establish continued access rules. Link session revocation design where identity lifecycle affects the matrix. Keep the test expectation aligned with documented policy instead of guessing how quickly revocation ought to take effect.

Test collection endpoints as carefully as individual records. A list can correctly return status success while including rows the actor cannot see. Assert the expected resource identifiers and absence of unrelated owners or tenants, including totals and pagination metadata. Counts can disclose protected information even when rows are filtered. Apply the same audience policy to search suggestions, summaries, and export counts where those endpoints share the underlying resource scope.

Keep failures diagnostic and maintainable

Name cases with actor, operation, and resource relation. Anonymous cannot read draft is more useful than permission test three. When a case fails, show the expected boundary and a safe summary of actual behavior. Avoid printing complete sessions or private fixtures into logs.

Use table-driven tests only when they remain readable and represent distinct policy cases. A huge generated cross product can obscure meaningful differences and create redundant maintenance. Add cases when a new role, route, field, or ownership relation changes the policy. Remove obsolete expectations deliberately. The objective is a reviewable set of boundaries that fails clearly when authority broadens by accident.

Use AI to search for missing combinations

Give an assistant the policy matrix, route inventory, response schemas, and fixtures. Ask which roles or resource relations are untested and whether any test mocks away the permission decision. Require file references for routes it claims are protected. Keep actual account data and session tokens out of the prompt.

Have it propose negative cases before generating code. Review those cases with product policy so the assistant does not invent administrator powers. After implementation, ask whether an unauthorized mutation could still satisfy the assertions. AI can make matrix review faster, but the suite needs executed evidence against the real trusted-context and data-access paths before it supports an authorization claim.

Sources

OWASP authorization guidance is the primary access-control reference.

Playwright test isolation guidance supports independent test state when browser-level coverage is used. The article-management role matrix is illustrative.

About the Author

Kamruz

Kamruz

Full Stack Developer

A passionate developer who loves creating modern web applications and sharing knowledge with the community.

More About Me

Related Articles