A testable promise instead of a general seal of approval
‘The API is secure’ leaves the data, users and flows unspecified. A useful promise might be: ‘An ordinary member may read only their team's exports; only the creator may edit drafts; a completed export job is not executed again on retry.’ Expected results can be derived from this.
First write down permitted cases. Some applications allow team sharing, others only personal access. A test indiscriminately prohibiting every record owned by someone else would be wrong where team sharing is intended. Then define negative cases: another identity, missing role, different tenant, forbidden field, invalid state or revoked access.
A permission matrix of caller, resource and action helps. OWASP Authorization Testing Automation describes this approach. Rules must come from your product contract, not merely repeat the code's incidental current behaviour.
A small environment of your own with controllable consequences
Use test identities and synthetic records of known origin. A suitable environment includes layers relevant to the question: authentication, actual application code, an empty test database and, for caching questions, the same proxy type, for example. Use test modes or local substitutes for external services. Real keys and customer data do not belong there.
Before starting, establish possible follow-up actions. An innocent-looking call may trigger emails, webhooks, costs or background jobs. Exclude real recipients, bound quantities and runtime, and use a controlled initial state. Test runs must not accidentally switch to the production address.
Also define cleanup: remove test records or reset the isolated database to its known starting state, revoke test keys and close temporary permissions. If an unexpected external action appears, stop the run and inspect the environment before continuing. Deliberately open or modified negative tests belong in a separate test copy.
Example: testing team exports
The following synthetic example has teams Blue and Green. Lea and Nils are ordinary Blue members, Mara administers Blue, and Sam belongs to Green. All team members may read their team's exports. Only the creator may edit an export while it is a draft. Only a team administrator may delete a completed export. These rules apply solely to the example.
On narrow screens, scroll the table sideways.
| Case | Expectation | Meaningful check |
|---|---|---|
| Lea reads her export in Blue. | Allowed. | The correct export appears, with permitted fields only. |
| Nils reads Lea's export deliberately shared with Blue. | Allowed. | Intended collaboration works. An owner-only comparison would be too strict here. |
| Sam from Green reads the same export. | Denied. | No export content or confidential metadata; data and side effects unchanged. |
| Nils attempts to change Lea's draft. | Denied. | The draft remains in the expected state at byte or field level; no change job is accepted. |
| Lea changes her own already completed export. | Denied. | The state contract applies despite identity and ownership. |
| Lea requests deletion; Mara requests it separately. | Lea denied; Mara allowed under the rules. | Role decision and actual effect are tested separately. Each case has its own initial record. |
| An unauthenticated client retrieves the list. | No protected content. | Status and response match the authentication contract; no complete list appears inside an error object. |
| Sam receives a list, search result or download link. | Only results approved for Green. | Counts, embedded objects and later retrieval paths also remain within the boundary. |
Depending on the API contract, expected rejection may use 403 or a concealing 404. Status alone is insufficient: an application might return an error after making an unauthorised change. Check both response and stored state, plus triggered follow-up work. A test must also establish that the test object exists and the permitted control case works; otherwise an accidentally wrong path may imitate successful rejection.
The articles on BOLA and IDOR, role permissions, field permissions and tenant isolation explain enforcement. Here you combine their rules into repeatable evidence.
Keep important cases in the normal development workflow
Collect test identities, data and expected results in readable fixtures. The following JSON excerpt describes one example test case. Its JSON syntax has been checked; it is not a complete test driver and sends no HTTP request.
{
"case": "green-member-cannot-read-blue-export",
"actor": "sam-green-member",
"resource": "blue-export-01",
"action": "read",
"expected": {
"decision": "deny",
"containsExportData": false,
"storedStateChanged": false,
"jobsCreated": 0
}
}
The test driver must call the real server-side entry points, use the prepared identity and verify the listed effects. An isolated helper-function test is useful but does not prove every route uses that function. Add suitable integration tests where routing, data access and follow-up actions meet. OWASP Authorization Regression Testing describes retaining such controls through changes.
Choose cases by possible harm and changed behaviour. New export functions need different negative cases from a pure error-text correction. After an authorisation defect is found, retain the relevant regression test. If the business rule deliberately changes, update expectation and rationale together; do not weaken a test merely because it reveals a defect.
Extend the matrix to actual application controls
On narrow screens, scroll the table sideways.
| Area | Suitable negative test of your own | Important limitation |
|---|---|---|
| Tokens and keys | Expired or revoked test credentials, wrong audience or wrong token type under your profile. | Decoding token content does not prove successful validation; valid identity does not prove object authorisation. |
| Input and response fields | Missing required field, wrong type, permitted boundary value, forbidden write field and unexpected response field. | A validator must run on the actual path; a schema is not a business rule. |
| Browsers and cookies | Allowed and disallowed test origins, real preflight and actual response, intended cookie/CSRF behaviour. | A command-line client does not reproduce browser rules. A CORS error does not prove no action occurred. |
| Limits and work | Use deliberately small test budgets to check the intended counter and rejection. | No load campaign is required. Such functional testing measures neither production capacity nor distributed enforcement during failure. |
| Retries and concurrency | The same synthetic job sequentially and under controlled concurrency; count results, state changes and jobs. | An idempotency key without atomic processing does not prove a single effect. |
| External responses and webhooks | Local valid, invalid, delayed and duplicate example data under the actual partner contract. | A valid signature replaces neither business plausibility nor processing control. |
| Operations | Trace a harmless defined test event through log, notification and responsible handling. | A metric's existence is not yet a working response path. |
This selection is no complete test catalogue. For systematic expansion, use suitable requirements from the OWASP Application Security Verification Standard, citing the exact version. Scope and required depth must suit the application. A blanket claim of being ‘OWASP tested’ obscures what was actually examined.
Where a public response probe helps
The API Security Check examines defined public GET/OPTIONS responses and a limited GET error probe. It can interpret visible CORS, method, header or server information, for example. It provides no evidence for your role matrix, tenant isolation or business logic. It does not discover every endpoint in your application either.
Use such a finding for the question it can answer: what was visible at this specified target under the check's conditions? Keep it distinct from authenticated integration tests and configuration review. A result without visible anomalies leaves untested questions open. The HTTP findings guide helps interpret it; reports document the same limited measurement.
Document a result the team can work with
A useful test record names the promise, tested revision, environment, synthetic roles used and observed response with its effect. Secrets do not belong in the report. State specifically what was omitted: an unavailable partner test mode, a browser policy not reproduced or behaviour under concurrent processes not yet tested, for example.
Separate three outcomes: the expectation is supported by evidence, the expectation was violated or the case could not be meaningfully tested. An unreachable endpoint belongs to the third group. A good overall grade cannot replace that state. Fix a concrete defect and repeat the affected case plus closely related permitted flows.
If you must roll back a change, also check the security state restored by it. An old version may work reliably while reintroducing the same known authorisation flaw. Where potential harm is high or major questions remain, plan an independent technical review with clear environment and scope. Product acceptance rests on this evidence and remaining risks; this guide does not grant it automatically.
Sources and example limitations
Sources checked on 27 September 2026: OWASP Authorization Testing Automation, Authorization Regression Testing, ASVS, API Security Top 10 2023 and RFC 9110. Team rules and data are fictional. No production or third-party API was tested with them.