Where is a request actually controlled?
Each control blocks something different. A WAF mostly filters known HTTP attack patterns where the request matches a rule. A rate limit rejects requests over a configured volume, rate, or burst. Schema validation blocks fields, types, sizes, and ranges outside the API contract. Strict JWT validation stops the acceptance of tokens whose signature or MAC is wrong, or whose issuer, audience, or expiry conditions do not match. mTLS blocks connections from a peer that does not hold a trusted certificate and its private key. An API gateway is a placement point where these policies can run, but not every gateway product offers the same security features.[1]
Applying all six does not complete API security. A user reading someone else's order, an ordinary user calling an administrative function, a well-formed request cornering stock or reservations — all of those still have to be decided in business logic and authorization. Unknown APIs, key and certificate lifecycle, logging, and audit are separate areas of responsibility.[6] So the question that comes before "do we have a WAF" or "did we deploy a gateway" is which threat is rejected at which point, and what gap remains behind it.
A request passes six points. First is the client or calling service. A JWT carries claims and token context here, and where mTLS is used the client certificate proves private key possession. The JWT itself does not perform user authentication or the authorization decision. Second is the edge and the WAF, which inspects HTTP headers, URI, and body against rules, detects known injection and traversal, and mitigates some layer 7 anomalies. Third is the API gateway or ingress, which selects route and method, runs JWT, mTLS, rate, and schema policy depending on product and configuration, and handles routing, logging, and telemetry — none of which should be assumed built in as standard. Fourth is the runtime and API handler, holding authoritative parsing and schema validation, timeout, payload, query, batch, and concurrency limits, and the check of service and token context. Fifth is business logic and authorization, which owns object and property-level authorization, function-level authorization, and business flow, state transition, amount, and stock rules. Last is data, queues, and downstream APIs, with databases, caches, queues, external APIs, file storage, downstream credentials, egress, and data policy. Cutting across all six are API inventory, secret, key, and certificate lifecycle, logging, monitoring, and audit.
What matters is that a direct-origin or internal bypass between gateway and runtime skips the controls in front. NIST notes that once the premise of every request passing the central gateway breaks, policy can be bypassed. If an internal service-to-service path, an old hostname, a direct origin address, or a separate version does not cross the same controls, "we configured it at the gateway" does not prove coverage.[1]
What each blocks, assists with, and cannot do
The WAF entry here is scoped to a WAF itself. Some WAAP products also provide rate limiting, bot management, DDoS defence, and API discovery, but those capabilities are not folded into the intrinsic ability of a WAF. NIST describes a WAF as rule-based control over HTTP payload and metadata. OWASP CRS likewise offers general detection rules as a starting point and does not understand an individual API schema or business meaning.[1][10]
An API gateway is not a single feature name from a security standard either. A gateway may support JWT, mTLS, rate limiting, and schema validation, yet actual enforcement varies by product, deployment pattern, licence, and configuration. That a gateway supports a policy and that the policy is enforced on every route are separate facts.[1]
A JWT is not authentication or authorization in itself. The JWT that RFC 7519 defines is a representation format carrying claims. A JWT protects integrity through JWS signature or MAC, or encrypts through JWE, but nothing is encrypted merely because it is a JWT. The receiver has to verify algorithm, signature, issuer, audience, time conditions, and token type, and how the verified claims translate into permission is a separate policy.[3]
mTLS proves that the TLS peer holds the private key matching its certificate. With RFC 8705 certificate-bound access tokens, an attacker holding only a stolen bearer token is also limited from reusing it. Whether the service holding that certificate may read order/123, and whether the end user behind it may run an administrative function, is still decided by authorization.[4]
An OpenAPI or JSON Schema document does not block requests on its own. It becomes a control when a validator reading the schema actually runs at the gateway or runtime and rejects mismatching requests. Correct structure and types do not mean "this user may modify this order" or "this amount and state transition are valid business".[5]
- JWT
- A JWT is a representation format that carries claims, not authentication or authorization in itself. It becomes a control only when the receiver verifies the algorithm, signature, issuer, audience, time conditions, and token type.
- mTLS
- mTLS proves that the TLS peer holds the private key matching its certificate, and it does not decide which resources that peer may act on.
- Schema validation
- Schema validation is a validator at the gateway or runtime actually rejecting requests that break the contract, which is a different thing from publishing an OpenAPI document.
Control | Blocks directly | Mitigates or assists | Does not resolve | Common misconfiguration | Enforcement point |
|---|---|---|---|---|---|
| WAF | SQL injection, XSS, path traversal, and malformed HTTP payloads matching the ruleset | Repeated known attacks, some layer 7 anomalies, attack surface reduction before runtime | Object and function authorization, well-formed business logic abuse, shadow APIs, service identity | Left in detection-only, high blocking thresholds, excessive rule exclusions, an aging CRS, direct-origin bypass | CDN, reverse proxy, load balancer, edge adjacent to the gateway |
| API gateway | Routes and methods actually configured, TLS policy, built-in or integrated auth, rate, and schema policy | Policy centralisation, routing, common logs, token context propagation | Features the product lacks, requests that bypassed the gateway, fine-grained object ownership and business state | Assuming a gateway means protection, default-allow, unregistered routes, untrusted forwarded identity headers, per-environment policy drift | API ingress, gateway, service mesh ingress |
| Rate limit | Volume, rate, and burst overruns for the same identifier within the policy scope | The speed and cost of brute force, scraping, enumeration, and resource abuse | Full DDoS, distributed low-and-slow, business abuse under the threshold, one expensive request | Keying on IP alone, one threshold for every endpoint, limiting only total traffic, exempting internal calls, no concurrency or cost limit | Applied separately at edge, gateway, runtime, and downstream |
| Schema validation | Fields outside the contract, wrong types, missing required values, declared size and range violations | Parser surface reduction, lower mass assignment exposure, control of oversized payloads and response data | User permission, object ownership, state transitions, business meaning such as price, stock, and reservation | Publishing an OpenAPI document without enforcing it, over-permissive additionalProperties, assuming format is always asserted, validating after deserialisation | Gateway validator, runtime, serializer |
| JWT validation policy | Forged or altered tokens, disallowed algorithms, wrong issuer or audience, expired or not-yet-valid tokens | Supplying verified identity, scope, and claims to the authorization decision that follows | The authentication procedure itself, object and function authorization, replay of a stolen bearer token, key lifecycle | Decoding without verifying, skipping iss and aud, algorithm confusion, trusting attacker-controlled kid or jku, long-lived tokens, token logging | Gateway, resource server, runtime |
| mTLS | TLS connections from a peer that cannot present a trusted certificate and prove possession of its private key | Service identity, B2B client authentication, reduced stolen-token replay through certificate-bound tokens | End-user object and function authorization, business intent, a malicious client holding a valid certificate | Sharing one certificate, checking only that a trusted CA issued it without mapping identity, forgeable headers after proxy termination, expecting replay protection without token binding | TLS endpoint, gateway, service mesh sidecar, runtime |
Shape delivery around the content — Set caching by update behavior and observe edge delivery alongside origin load.
Which control rejects which threat directly
The grades below are not grades any standard supplies. They are an editorial synthesis, against this article's questions, of the capabilities, prerequisites, and limits described in the API protection controls and gateway patterns of NIST SP 800-228,[1] the BOLA, resource consumption, BFLA, sensitive business flows, and inventory entries of OWASP API Security Top 10 2023,[2] the JWT representation and validation requirements of RFC 7519,[3] the mTLS client authentication and certificate-bound tokens of RFC 8705,[4] the contract and structure validation scope of OpenAPI 3.2.0 and JSON Schema,[5] and the general attack detection rules of OWASP CRS.
Three caveats attach to the table. First, mTLS blocks ordinary bearer token replay only where the token is bound to the certificate in the RFC 8705 manner and the resource server verifies that binding. Second, schema validation reduces undeclared properties and mass assignment surface but does not decide object ownership. Third, a shadow API that really does pass the same WAF receives the protection of the general ruleset, but coverage cannot be proven while its existence and path are unknown.
Threat or abuse | WAF | Gateway | Rate | Schema | JWT | mTLS | Control that must remain |
|---|---|---|---|---|---|---|---|
| Known HTTP attack patterns matching the ruleset | ● | △* | △ | △ | — | — | Secure coding, runtime patching, parameterized queries |
| Fields, types, sizes, and ranges outside the API contract | △ | △* | — | ● | — | — | Versioned contract, runtime parser agreement |
| Volume or burst overrun from the same caller | — | ●* | ● | — | △ | △ | Distributed identity, quota, cost and concurrency limits |
| One expensive request, oversized batch, query, or concurrency | △ | △* | △ | △ | — | — | Timeouts, payload, page, and query bounds, circuit breaker |
| Volumetric or distributed DDoS and upstream saturation | △ | △* | △ | — | — | — | Network DDoS mitigation, capacity, load shedding |
| Forged, altered, wrong-issuer or wrong-audience, expired JWT | — | ●* | — | — | ● | — | Issuer and key trust, issuance and revocation policy |
| Replay of a stolen bearer token | — | △* | △ | — | — | ● | Short lifetimes, revocation, sender-constrained tokens |
| Connections from an untrusted service or B2B client | — | ●* | — | — | △ | ● | Service authorization, end-user context |
| Object and property-level authorization flaws | — | △* | △ | △ | △ | — | Object ownership and field policy in the runtime |
| Function-level authorization flaws | — | ●*/△ | △ | — | △ | — | Route, method, role, and business function policy |
| Business logic abuse in well-formed requests | — | △* | △ | — | △ | — | Per-flow risk rules, state transitions, human approval |
| Unknown, shadow, and legacy APIs bypassing controls | △ | △* | — | — | — | — | API inventory, owner, version, retirement |
| Secret, signing key, and certificate lifecycle failures | — | △* | — | — | — | — | KMS and PKI, rotation, revocation, secret management |
| Monitoring and audit gaps | △ | △* | △ | △ | △ | △ | Central logs, correlation, retention, alerting, periodic review |
The gaps the six controls leave behind
OWASP classifies BOLA as a code and policy problem to be checked at every endpoint that handles an object. Reading a user ID out of a JWT does not prove permission over the object that was requested.[2]
Function-level authorization is similar. That a route exists and a JWT is valid is a different fact from that this user may run the function. Even where explicit route, method, and role policy is enforced at the gateway, insufficient product capability or policy expressiveness means the runtime has to check again.[7]
Business logic abuse depends even more on the business. The stock hoarding, reservation squatting, and referral automation OWASP cites are usually well-formed, authenticated requests, so schema validation or mTLS alone cannot separate malice and business harm.[8]
API inventory is a precondition for this article, and the build method belongs to the API inventory operating document. Here it is used only to the point that coverage cannot be proven without knowing which APIs, versions, owners, external exposure, and retirement states exist. As in the OWASP example, applying a rate limit only to the current API while leaving a beta host in place lets an attacker pick the unprotected path.[9]
Gap | Why six controls are not enough | Additional control required | Primary enforcement point |
|---|---|---|---|
| Object-level authorization | A user with a valid JWT can request another user's object ID. A WAF and a schema do not know who owns the object | Check calling identity, tenant, object owner, and relationship on every request | Runtime, authorization service, data access layer |
| Function-level authorization | An authenticated ordinary user can call an administrative route or method | A default-deny policy tying route, method, role, and scope to real business functions | Both gateway and runtime |
| Business logic abuse | Even with valid form and permission, stock hoarding, reservation squatting, and referral abuse remain possible | Per-flow rate, ordering, state transition, amount, stock, device, and risk rules | Business logic, fraud and risk engine |
| Unknown / shadow API | Without knowing the API, you cannot prove whether WAF, gateway, rate, or schema policy applies to it | API inventory, owner, version, exposure, and retirement state | API governance, platform, security |
| Secret / key lifecycle | JWT and mTLS do not replace safe generation, distribution, rotation, revocation, and leak response for keys and certificates | KMS, HSM, PKI, secret manager, rotation, revocation, emergency rollover | Identity, platform, security operations |
| Monitoring / audit | Individual controls produce logs without reconstructing a whole incident or proving accountable change | Correlation ID, central logs, decision log, retention policy, alerting and periodic review | Cross-cutting across every layer |
Check prerequisites and misconfiguration per control
For the shared architecture, five things matter. It is known which host and version external, internal, partner, and legacy APIs run on. Every external request crosses the intended edge and gateway, with direct origin, old hostname, and separate-port bypasses closed. Each policy has an authoritative enforcement point and an accountable team. Where gateway and runtime policies conflict, it is settled which one governs. Policy changes are version-controlled as code or configuration, and per-environment drift is detected.
For the WAF, check that it can actually parse the HTTP methods and content types in use, that a currently supported ruleset and engine are in place, and that detection logging and real blocking behaviour were verified separately. Rule exclusions are minimised to route and parameter scope with reason, expiry, and owner recorded. False positives that block legitimate requests, and self-inflicted denial through response rules, have been tested. Direct connection to the backend around the WAF is not possible.
For the API gateway, check that routes and methods are registered explicitly and unregistered routes are denied by default, and that JWT, mTLS, rate, and schema policies are enforced per route rather than merely supported. External clients must not be able to inject the user and certificate headers the proxy forwards. Internal calls that do not cross the gateway carry an equivalent policy or a separate trust boundary. Fail-open and fail-closed behaviour is decided in advance for gateway and policy store outages.
For rate limiting, check that identifiers beyond IP — user, client, tenant, route, operation — can be used, and that functions with different cost and risk such as login, search, upload, and payment carry separate policies. Beyond requests per second, limit burst, concurrency, batch size, page size, processing time, and external API cost. Limit state has to be shared consistently across distributed gateways and runtimes. Internal services and privileged clients are not trusted without limit. Limit responses and retry policy must not create a client retry storm.
For schema validation, state the version and dialect of OpenAPI and JSON Schema, and confirm the specification is enforced in a gateway or runtime validator rather than living only in a document. Define required, types, lengths, ranges, array sizes, and additional-property policy. Confirm that format behaves as an assertion in the validator in use. Test that validation results do not change before and after deserialisation and type coercion. Validate not only requests but responses that could over-expose sensitive data. Tie schema change to API version and backward compatibility policy.
For JWT validation, fix allowed algorithms as an allowlist. Separate token decoding from cryptographic verification. Verify signature, iss, aud, exp, and where needed nbf and token type. Restrict headers such as kid, jku, and x5u so they cannot become arbitrary key lookup, SSRF, or injection paths. Give tokens an explicit type so different token kinds are not confused under one validation rule. Keep access tokens out of URLs, application logs, and error reports. Maintain short token lifetimes and key rotation, revocation, and emergency withdrawal procedures. Never mistake JWT claims for the final object or function authorization result.
For mTLS, map not only the trusted CA but the SAN or certificate attributes onto real client and service identity. Issue a distinguishable certificate per client and service. Automate issuance, renewal, revocation, and leak response, or assign operational ownership. Where TLS terminates at a load balancer, make the certificate identity metadata passed to the backend unforgeable. Document the trust boundary — whether mTLS is required at every hop or verified once at the edge. Where replay protection is the goal, configure certificate-bound token verification rather than plain mTLS. Never treat mTLS identity and end-user identity as the same subject.
For monitoring and audit, check that every deny decision records the control, policy version, route, client or user, result, and reason code. Link WAF, gateway, runtime, authorization, and data logs through one correlation ID. Redact tokens, secrets, and personal data out of logs. Alert separately on block, bypass, policy error, and fail-open states. Retention period, access rights, integrity, and periodic review ownership are settled, and control policy changes and exception approvals are auditable.
Inspect and protect requests before they reach the service — Review request and blocking records, tune protection rules and manage certificates and access controls.
Review the gaps with ten questions
If the answer to any question below is no, a control gap remains regardless of whether a WAF, gateway, or JWT was deployed. Each question carries the evidence that supports the answer — test results and logs, not a screenshot of a settings page.
Gap | Review question | Evidence needed |
|---|---|---|
| Object-level authorization | Is the current user, tenant, and relationship verified per request for every object ID and property? | Authorization test, deny log, tenant isolation test |
| Function-level authorization | Are the allowed routes, methods, and business functions per user, admin, and service account defined default-deny? | Route policy, role matrix, negative test |
| Business logic abuse | Have you defined the conditions under which a well-formed, authorized request still harms stock, reservations, payment, coupons, or referrals? | Abuse scenario, flow limit, state transition test |
| Unknown / shadow API | Do you know every host, environment, version, owner, exposure, and retirement state? | API register review and the API inventory operating document |
| Secret / key lifecycle | Is ownership assigned for generation, distribution, rotation, revocation, and leak response of signing keys, client secrets, and certificates? | KMS and PKI policy, rotation record, emergency runbook |
| Monitoring / audit | Can you reconstruct afterwards who produced which result on which route and object? | Correlated decision log, retention, alert test |
| Control bypass | Do direct origins, internal routes, and beta or legacy hosts avoid bypassing edge and gateway policy? | Network path test, route inventory, firewall policy |
| Resource bound | Beyond call counts, are processing time, payload, batch, concurrency, and external cost also bounded? | Limit configuration, load and abuse test |
| Policy failure | Do you know whether a WAF, gateway, key provider, or rate store outage fails open? | Failure injection results, break-glass policy |
| Change safety | Can a control policy change be verified in a small scope and reversed? | Versioned policy, canary and rollback evidence |
Decide the combination in six steps
Start by confirming the premise that the APIs to protect are identified; the build method belongs to the API inventory operating document. Next, write threats as concrete sentences: injection, a client without a certificate, replay of a stolen token, BOLA, stock hoarding. Then name, for each threat, the point that rejects it first and the point that is finally accountable for it. Split the six controls into those that block directly and those that only assist. Assign an owner and evidence to the items the six do not resolve — object and function authorization, business logic, key lifecycle, monitoring. Finally, confirm through negative tests and bypass-path tests that the policy runs on the live request path.
What matters in API security controls is not how many are deployed but whether you can state which request each one rejects under which condition. If object authorization, business logic, shadow APIs, key lifecycle, or audit is missing from that statement, the architecture still has a blank in it, however many security products are in place.



