All resources
// Resources

OWASP API Security Testing Checklist for Engineering Teams

Published June 9, 2026

Evidence-led API release review

Start with a release manifest, not category names. For each operation, write the caller, method, input schema, returned data, state change, downstream dependency, and product decision it supports. A gateway export might show POST /v2/invoices/export while an OpenAPI file omits it; that discrepancy stays open until its owner explains whether it is retired, private, or live. Diff the manifest against deployment routes on every release.

Work one row at a time. A change to a user profile should be tested with an allowed field, denied field, foreign object reference, malformed body, repeated submission, and maximum permitted payload. Expected output includes HTTP status, response fields, database state, queue state, audit event, and any provider invocation. The reviewer needs a test account map and timestamped redacted captures, not a statement that “the endpoint was checked.”

A release fails when a state-changing operation lacks both positive and negative tests, when test data cannot identify its owner, or when gateway and contract disagree. Remediation is specific: add a service authorization decision, cap a paginator, remove an obsolete route, or document a partner callback with authentication requirements. After repair, rerun only the case that failed plus a neighboring operation using same middleware, then attach those two results to the release record.

Build a test ledger with operation ID, risk hypothesis, fixture, expected HTTP output, expected state, owner, and evidence link. A change review should reject a new operation that has no ledger row. Compare negative access result with allowed request using same shape so status differences reflect policy, not malformed input. For asynchronous work, query job state after denial and verify no email, file, or callback was produced. The closure artifact is ledger diff plus machine-run regression reference.

Checklist execution record

Number every operation in an API release ledger. Record its caller class, data sensitivity, object reference, write effect, maximum response size, dependency, and rollback behavior. POST /accounts/{id}/close needs a different test set from GET /accounts/{id}: closure may trigger a queue, notification, retention workflow, and permission change. Attach contract diff and gateway diff to same ledger row.

Run a controlled positive request, then change one condition at a time: caller role, tenant ID, body property, pagination value, content type, replay key, and timeout. Expected result names HTTP status, visible fields, database state, job state, and provider calls. Capture both request IDs and query post-condition; a denied response is insufficient if an email or export appears later.

Release reviewer fails a row with no owner, no negative case, or no evidence location. Fix missing route contract before deploy; fix a state leak at service boundary; fix a quota gap before expensive dependency. For asynchronous work, query completed and failed jobs after test window. Final record contains regression test name, patch reference, risk owner decision, and retest timestamp. This is release evidence, not a claim that any external standard has certified system.

Additional mechanism checks

When a contract lists bulk operations, split tests by element and transaction rule. PATCH /users may reject unknown properties but still permit mass assignment through a nested preference object. Capture serialized input after validation, not only controller output. For output, assert allowlisted fields: a 200 response with password-reset metadata or internal role flags is failure even if access decision succeeds. Mark evidence freshness; a test run before gateway policy changed does not approve later route. Checklist owner reviews new dependencies because an upstream webhook or file store can introduce separate authorization and resource paths.

Contract-to-runtime reconciliation

Take gateway export and OpenAPI contract from same release candidate. Normalize method and path, then identify operations present in only one source. For each mismatch, inspect deployment route and client usage before assigning owner. A retired endpoint passes only when it returns no business data and monitoring shows migration behavior expected by product. This check prevents documentation from becoming an optimistic inventory.

For a worked property-update case, send valid displayName, then send role, tenantId, and nested preferences.plan. Compare persisted columns and emitted domain events. Return 400 or 403 according to validation policy, but never echo rejected sensitive values. Follow with an allowed request to prove rule did not block legitimate update. Store response schema assertion and database query result alongside release row.

An exception is a named operation with a migration date and compensating limit, not a generic waiver. When date arrives, remove gateway allowance and run a route probe. If probe still reaches handler, keep release blocked until deployment artifact is corrected.

Release artifact

OperationOwnerStatusEvidenceExpected resultActual resultExceptionClosure
POST /v2/invoices/exportbilling service ownerConditionalgateway/OpenAPI diff, denied request ID, job-state query, audit eventforeign tenant gets 403; no export job, file, or callback403 returned; no job or file; route absent from OpenAPIpartner route remains undocumented until 2026-06-30 with gateway quota and named approveradd contract entry, rerun denied and allowed cases, link regression run to release ledger

Sources

Have a system that needs testing?