API Security

APIs are now the dominant attack surface of the cloud-native enterprise - every mobile client, every partner integration, every microservice, every webhook is an API call. This is the vendor-neutral practitioner's guide: the OWASP API Top 10 walked through one item at a time, authentication and authorization patterns, the BOLA problem, rate limiting, the API-gateway landscape, schema validation, GraphQL and gRPC specifics, SSRF, discovery and inventory, runtime defense platforms, testing, and the AWS / Azure / GCP native tooling - followed by maturity stages and the pitfalls that show up in nearly every program.

Bundles of network cables converging into a switch, illustrating API traffic flow
Photo by Brett Sayles on Pexels

· · Vendor-neutral · View source on GitHub

The 30-second version: APIs are the dominant attack surface of any modern cloud-native business - the OWASP API Top 10 exists because the bugs are different from web-app bugs. WAFs, CSP headers, and code-scanning miss most of them because the worst API issues (BOLA, BFLA, BOPLA, unrestricted resource consumption) are business-logic failures that look like legitimate traffic.

The pragmatic stack: an API gateway that enforces auth, rate limiting, and schema validation; OAuth 2.0 / OIDC for delegated auth, with JWT validation done carefully; fine-grained authorization per object (BOLA-by-design); schema-first APIs validated at the edge; discovery tooling so shadow APIs surface; and a runtime API security platform that watches the traffic for the business-logic abuses signatures can't catch.

On this page

  1. Why API security is its own discipline now
  2. The OWASP API Security Top 10 (2023)
  3. Authentication patterns
  4. Authorization patterns
  5. The BOLA problem
  6. Rate limiting
  7. API gateway landscape
  8. Schema validation
  9. GraphQL-specific risks
  10. gRPC-specific concerns
  11. SSRF prevention in APIs
  12. Discovery & inventory
  13. Runtime API security platforms
  14. API testing
  15. Webhooks security
  16. Third-party API consumption
  17. APIs in the service mesh
  18. AWS, Azure, and GCP side-by-side
  19. Maturity stages
  20. Common pitfalls
  21. Further reading
  22. FAQ
  23. Where next

Why API security is its own discipline now

The web in 2010 was rendered HTML; the web in 2026 is the JSON behind the rendered HTML, plus mobile clients, plus B2B integrations, plus webhook callbacks, plus the service-to-service traffic inside your own cluster. The API is the product surface, and it's the attack surface.

The shift created bugs the application-security toolchain didn't anticipate. A ModSecurity rule set is unhelpful against an authenticated user asking for someone else's order. A Content-Security-Policy header doesn't apply to a mobile client or a partner pulling from a webhook. SAST tooling that grep'd for SQL injection patterns doesn't catch that GET /api/orders/{id} never re-checks ownership.

The category is now formal enough to have its own OWASP top-10 (2019 first edition, 2023 the current), its own analyst category (Gartner's "API security" was carved out of WAF in 2021), and a dedicated vendor landscape (Salt, Traceable, Noname/Akamai, Cequence, Wallarm, 42Crunch). If you operate non-trivial APIs and you're treating API security as "the WAF will catch it," you are operating on a 2015 model of the web.

What changed

The OWASP API Security Top 10 (2023)

The OWASP API Top 10 is the de-facto checklist. The 2023 edition reflects a maturity shift from 2019 - BOLA still dominates, but the list now reflects how often authorization, not authentication, is the failure mode. Walking through each:

API1:2023 - Broken Object Level Authorization (BOLA)

The single most common API bug. The endpoint authenticates the caller and confirms they can call this kind of endpoint, but does not check whether the specific object referenced in the request belongs to that caller. GET /api/orders/1247 returns order 1247 regardless of who owns it. See the BOLA section for the architectural defense.

API2:2023 - Broken Authentication

Tokens that can be forged, replayed, brute-forced, or stolen via misconfigured flows. The dominant cases: JWTs accepted without signature verification, OAuth flows that don't validate the audience, password-reset flows that leak tokens, and authentication endpoints without rate limiting. Treat the auth surface as critical; subject it to dedicated review and rate-limit it harder than anything else.

API3:2023 - Broken Object Property Level Authorization (BOPLA)

The endpoint correctly checks that the caller owns the object, but does not check which properties they can read or write. Mass-assignment (the caller PATCHes {is_admin: true} and the server accepts it) is the write side; over-fetching (the caller GETs the object and the response includes fields they shouldn't see) is the read side. Defended by allowlisting properties in DTOs, never spreading user input into the model, and never returning the model directly.

API4:2023 - Unrestricted Resource Consumption

The endpoint accepts a request that costs the server far more than the caller. Examples: pagination with no max page-size, file uploads with no size limit, search queries with no time budget, deeply nested GraphQL queries, batch endpoints with no batch-size cap. Defended by per-endpoint quotas, per-user budgets, query-complexity limits, and circuit breakers on downstream calls. The relevant cloud-cost angle: an attacker exploiting this against your serverless API may not breach data but will breach your AWS bill.

API5:2023 - Broken Function Level Authorization (BFLA)

The same shape as BOLA but for functions rather than objects: the caller can invoke an admin-only function because the function-level check is missing. POST /api/admin/users/123/delete succeeds for a non-admin caller because the admin role-check is in the UI, not the API. Defended by central authorization middleware that enumerates required permissions per route, with deny-by-default.

API6:2023 - Unrestricted Access to Sensitive Business Flows

The endpoint is technically working as designed but is being abused at scale - bulk account creation, ticket scalping, gift-card balance enumeration, scraping product catalogs. The auth and authorization pass; the abuse is in the volume. Defended at the platform layer: behavioral analytics (the API security platforms are heavily focused here), bot management, fraud-detection signals, and stepped-up auth for high-value flows.

API7:2023 - Server Side Request Forgery (SSRF)

The API accepts a URL from the client and fetches it on the server - image-import, webhook-test, URL-preview, OAuth-callback features all do this. An attacker supplies a URL pointing at the instance metadata service, an internal admin endpoint, or a cloud-internal API. See SSRF prevention for the defense pattern.

API8:2023 - Security Misconfiguration

The grab-bag: verbose errors revealing stack traces, CORS misconfigurations that allow any origin, missing security headers, default credentials on management endpoints, debug routes left enabled, GraphQL introspection in production, gRPC reflection in production. Defended by baselined gateway configs, a security-config policy that lives in the IaC, and CSPM-style scanning of API gateways and APIM resources.

API9:2023 - Improper Inventory Management

Old API versions still deployed (v1 of the API was supposed to be off; it isn't), staging environments accessible from the internet, deprecated endpoints with weaker auth still online, and the broader "shadow API" problem of endpoints nobody knows exist. The inventory problem is now a first-class top-10 item - see discovery & inventory.

API10:2023 - Unsafe Consumption of APIs

The flip side - your code calls a third-party API and trusts the response without validation, exposing you to vulnerabilities the upstream introduces. Compromised upstream provider returns malicious payloads, or unsafe deserialization on response data. Defended by validating responses the same way you validate requests, timeouts and circuit breakers on outgoing calls, and treating third-party API responses as untrusted input.

A hand holding a small padlock against a circuit pattern, symbolic of API authentication and authorization
Photo on Pexels - auth is the gate but not the whole story.

Authentication patterns

The credential the client presents and how you validate it. The five patterns you'll encounter:

API keys

An opaque string the caller includes in a header. Fine for low-risk, low-value, server-to-server contexts where rotation is procedural and the blast radius of a leak is small (read-only public datasets, sandbox environments, "click here for a free key" demo APIs). Not fine for anything that touches user data - there's no user identity, no expiration by default, and no way to scope an individual call. If you use API keys, at minimum: rotate them on a schedule, scope them per-environment, log every use, and rate-limit them aggressively.

OAuth 2.0 / OIDC

The dominant pattern for any non-trivial API in 2026. OAuth 2.0 is the authorization framework - how a client gets a token to call your API on a user's behalf. OIDC is the identity layer on top - how the client learns who the user actually is. Use OIDC for user authentication, OAuth 2.0 for delegated access. Implement OAuth 2.1 conventions: PKCE everywhere, no implicit flow, no password grant, refresh-token rotation. The grant flows you'll actually use: authorization code + PKCE (web and mobile), client credentials (service-to-service), device code (TVs, CLIs).

JWT (and the pitfalls)

A JWT - JSON Web Token - is a signed (and optionally encrypted) blob of claims that the bearer can present to APIs. It's a transport, not an auth system. The pitfalls are notorious enough that JWT validation has its own published guide (RFC 8725 - JWT Best Current Practices). The recurring failure modes:

mTLS

Mutual TLS - both ends present certificates. The strongest authentication on the network: a certificate can't be replayed off the wire by an HTTP intermediary, and the lifecycle is enforced by the CA. The operational cost is real (cert issuance, rotation, revocation, partner onboarding), so mTLS shows up most where the data is sensitive enough to justify it: service-to-service inside a service mesh, high-value partner integrations, and any compliance regime that mandates client authentication.

Session cookies (for browser-fronted APIs)

If your API is consumed only by your own browser SPA on the same origin, a session cookie set after a login still works - Secure, HttpOnly, SameSite=Strict (or Lax, depending on cross-tab needs), and a server-side session store. The advantage is browser-supplied CSRF/XSS defenses; the cost is no mobile or partner support. Most modern stacks use OAuth even for the SPA so the same backend supports browsers, mobile, and partners with one auth model.

Authorization patterns

Authentication says "this caller is X." Authorization says "X is allowed to do Y on resource Z." The dominant models:

RBAC - Role-Based Access Control

Permissions group into roles; users have roles. The simplest mental model, the easiest to audit, and what most internal admin tools and many B2B SaaS apps run on. Limitations show up when permission decisions depend on the resource itself (ownership, project, organization, classification) - at which point you bolt on ABAC or move up the stack.

ABAC - Attribute-Based Access Control

Decisions evaluated against attributes - user attributes, resource attributes, environment attributes, action attributes. More expressive than RBAC for the "this user can read this object because they own it AND we're in business hours AND the object isn't classified" case. Harder to reason about; usually expressed in a policy language.

The policy-as-code stack: OPA, Cedar, AuthZed/SpiceDB, Topaz

Scopes vs roles

OAuth scopes are coarse permissions attached to a token at issuance ("this token can read calendars, not write them"). Roles are user-attached permissions resolved at request time. They serve different layers: scopes are what the user delegates to the client; roles are what the user is allowed to do, period. A common confusion: trying to express fine-grained per-object permissions as scopes (token explodes), or expressing client capability as roles (the user logically can do it, but you wanted to limit this app). The pragmatic split: scopes for client capability, roles/policies for user permissions, evaluated together at the API.

The BOLA problem

BOLA - Broken Object Level Authorization - is API1 on the OWASP top-10 for a reason. Almost every API has it somewhere, at least once in the codebase's history, because the bug fits naturally into how developers write controllers.

Why it's nearly universal

A typical handler:

@app.get("/api/orders/{order_id}")
def get_order(order_id, user=current_user):
    order = db.orders.find(order_id)
    return order

The framework's auth middleware confirmed current_user is logged in and can call this route. The handler looks up the order and returns it. The missing check: does this user own this order?

The check is easy to write, but it has to be written into every handler that takes an object id - and one missed handler is a complete data-disclosure bug. Multiply by every list-style endpoint that paginates over objects the caller may not own, every nested resource (/api/orgs/{org_id}/users/{user_id}/orders/{order_id} - three checks), every PATCH that targets an object id in the body, every search that returns ids the caller can then fetch directly.

How to design it out

The mature answer is to make BOLA architecturally impossible - the database query itself enforces ownership - rather than relying on every developer to remember the check on every handler.

Rate limiting

The crudest and most-effective control. Auth answers "who is calling?"; rate limiting answers "are they calling too much?" - and an attacker who can't make a million requests can't enumerate a million ids, brute-force a million passwords, or run a million expensive queries.

What to limit on

Algorithms

Three you'll see in practice. Token bucket - refills at a rate, each request consumes a token; allows controlled bursts. Sliding window - count requests in the last N seconds. Fixed window with leak - count per discrete time bucket, with smoothing. Token bucket is the default for most gateways; sliding window is preferred where exact rate enforcement matters (anti-abuse, payment).

Fair-use vs anti-abuse

Two distinct concerns that get conflated. Fair-use limits prevent any one customer from monopolizing capacity - generous, mostly never hit, primarily defensive against bugs in client code. Anti-abuse limits target adversarial patterns - login brute-force, scraping, enumeration - and should be tight, surfaced as 429s, and tied to step-up auth or temporary blocking. Run both layers.

Where it's enforced

API gateway landscape

The API gateway is the policy enforcement point for north-south traffic - auth, rate limiting, schema validation, routing, observability. The pragmatic landscape:

The choice usually breaks on three axes: how much you self-manage (Kong open-source vs Apigee managed vs Cloudflare edge), how cloud-native the integration is (AWS API Gateway is friction-free on AWS, friction elsewhere), and how strong the developer-portal and monetization story needs to be (Apigee and APIM lead here). For most cloud-native teams in 2026, the cloud-provider's gateway plus an API security platform layered on top is the right starting place.

Schema validation

The under-used control. If you declare what your API accepts - in OpenAPI 3.x, JSON Schema, or a protobuf definition - and enforce the declaration at the gateway, you eliminate an entire class of bugs: invalid types, oversized payloads, unknown fields (which is the mass-assignment defense), nested objects beyond a depth, arrays beyond a size.

The principle

"If it isn't in the schema, reject it" - the gateway returns 400 before the request ever reaches your handler. The handler can then trust that order_id is a UUID, quantity is a non-negative integer below the cap, and customer is an object with exactly the four allowed fields. Half of the input-validation bugs that show up in app code disappear at the gateway layer.

The mechanics

Spec-first vs code-first

Spec-first writes the OpenAPI doc first and generates code stubs from it; code-first writes the handlers and emits the OpenAPI doc from annotations. Spec-first produces cleaner, reviewable contracts and forces design before implementation. Code-first ships faster and stays in sync with the code automatically. The pragmatic answer: spec-first for partner-facing and v1 design; code-first with strict-mode validation for internal and iterative work. Either way: validate at the gateway, not just in tests.

Tooling

GraphQL-specific risks

GraphQL collapses many REST endpoints into one - and concentrates many REST-style bugs into different shapes.

Introspection in production

Introspection is the GraphQL feature that lets a client query the schema itself - every type, every field, every argument, every enum value, every deprecation. In development it's invaluable. In production, internet-facing, it's free recon for any attacker: they get a complete map of your API in seconds. Disable introspection in production or scope it to authenticated internal callers. Persisted queries (below) make introspection unnecessary for client builds anyway.

Query depth and complexity attacks

A GraphQL query can be arbitrarily deep - { user { friends { friends { friends { ... } } } } } - and a small query string can fan out to enormous server work. Defenses: maximum query depth (typically 7-10), maximum query complexity score (each field weighted; query must score below a cap), and request timeouts. Use a library - graphql-depth-limit, graphql-query-complexity, or the framework's built-in equivalent.

Batching attacks

GraphQL supports batching - multiple queries in one request. An attacker can pack many enumeration queries (e.g., login attempts with different passwords) into a single request and bypass per-request rate limiting. Defenses: limit batch size, count each operation against rate limits separately, or disable batching.

Persisted queries vs ad-hoc

Persisted queries - the client registers a query template by hash with the server, and at runtime sends just the hash and variables - narrow the attack surface dramatically. Only registered queries run; ad-hoc queries are rejected. Apollo, Relay, and most clients support it. Mature GraphQL APIs in production use persisted queries; introspection becomes a build-time concern, not a runtime one.

Field-level authorization

The schema alone doesn't enforce authorization - a query for user.salary is valid GraphQL regardless of whether the caller can read salaries. Authorization has to live in the field resolvers (or in middleware that wraps them). This is where most GraphQL implementations bleed BOLA / BOPLA: the schema is correct, the per-field check is missing.

Apollo Federation security

Federation composes multiple GraphQL subgraphs behind one gateway. The gateway and subgraphs must mutually authenticate (typically mTLS or signed JWTs), and subgraphs should not be directly reachable from clients. Misconfigured federation often leaves subgraphs exposed as full GraphQL endpoints with no auth - query them directly and skip the gateway's policy. Audit subgraph network reachability.

gRPC-specific concerns

gRPC is HTTP/2 + protobuf with strict typing - most of the input-validation problems REST and GraphQL face are eliminated by the wire format. Different concerns dominate:

Rows of servers in a data center - internal endpoints that should never be reachable through SSRF
The internal network behind your API - what an SSRF attacker is trying to reach.

SSRF prevention in APIs

SSRF - Server Side Request Forgery - is the bug where the server fetches a URL the attacker supplies. Common shapes: profile-picture URL fetch, webhook test endpoint, RSS importer, URL preview generator, OAuth callback URL, server-side image processing. The attacker's prize is access to the internal network - the metadata service, internal admin endpoints, the cloud's own APIs.

The classic targets

The defense pattern

API discovery & inventory

The shadow-API problem is now a top-10 OWASP item (API9, Improper Inventory Management) because almost every org has it. Endpoints that exist in production but aren't in the inventory: old API versions you forgot to turn off, staging environments accessible from the internet, services your team didn't know about, endpoints behind a feature flag that's silently on.

Three discovery sources

Tooling

Maturity goal: one inventory, deduplicated, that combines traffic, code, and cloud sources, with each entry mapped to an owning team and a documented data classification.

Runtime API security platforms

The new analyst category. Vendors that sit on or alongside API traffic, build a behavioral model, and detect the business-logic attacks WAFs miss. The major players:

What they catch

The platforms differ in deployment model (mirror / in-line / agent), where on the path they sit (CDN, gateway, sidecar, eBPF), and how heavily they lean on traffic analytics vs spec-based checks. Most large API estates end up with the WAAP / WAF for noise, plus one API security platform for the business-logic layer.

API testing

The testing toolchain mirrors AppSec: SAST-equivalent (scan the OpenAPI spec), DAST-equivalent (hit the running API with attack patterns), and fuzzing.

DAST for APIs

Fuzzing

Contract testing

Run schema linting (Spectral) in PR; DAST + fuzzing in nightly CI; manual Burp / ZAP for major releases; third-party pentests for critical APIs annually.

Webhooks security

Webhooks are the inverse of an API call - your system receives unsolicited HTTP POSTs from a third party (Stripe, GitHub, SaaS integrations). The defenses inherit some, invert others:

Third-party API consumption (you're being attacked through APIs you call)

API10 in the 2023 list - Unsafe Consumption of APIs - formalizes a class of risk most teams under-weight. Your code calls a third-party API and trusts the response. The upstream provider gets compromised, returns malicious data, and you ingest it.

APIs in the service mesh (east-west)

This page is the north-south view - clients on the outside, your APIs on the inside, the gateway in the middle. The east-west view - service-to-service traffic inside the cluster - is the service mesh page. The two are complementary:

Where they overlap: a request that arrived at the gateway with a user identity needs to propagate that identity through the mesh so downstream services authorize against the user, not against the calling service. Token propagation, RFC 9068 JWT profile for OAuth, and SPIFFE-style workload identity are the connective tissue.

AWS, Azure, and GCP side-by-side

The native API security capabilities each cloud ships, reduced to a one-screen reference:

Capability AWS Azure GCP
API gateway API Gateway (REST + HTTP), AppSync (GraphQL) API Management (APIM) Apigee, API Gateway
Auth integration Cognito, IAM, Lambda authorizers, JWT authorizers Entra ID, OAuth/OIDC, certificate auth, JWT validation Identity Platform, IAP, custom token verification
Fine-grained authz Verified Permissions (Cedar) Custom + Entra ID / RBAC IAM Conditions, custom
Rate limiting API Gateway usage plans, WAF rate-based rules APIM rate-limit policy, Front Door rate limiting Apigee quota policy, Cloud Armor rate-based rules
Schema validation Request validators (OpenAPI in import) APIM validate-content policy Apigee OASValidation policy
API security platform None native (3rd party); WAF + Inspector Microsoft Defender for APIs (in APIM) Apigee Advanced API Security
WAF for APIs AWS WAF + Bot Control + Fraud Control Azure WAF on Front Door / App Gateway Cloud Armor with reCAPTCHA Enterprise
Discovery Across accounts via Config + custom; 3rd party CSPM/CNAPP Defender for APIs auto-discovery within APIM Apigee API Hub, SCC asset inventory
mTLS support API Gateway custom domain w/ truststore (S3-hosted) APIM client certificate auth Apigee mTLS, Cloud Load Balancing mTLS
Observability CloudWatch, X-Ray, API Gateway access logs App Insights, APIM diagnostics, Log Analytics Cloud Logging, Cloud Trace, Apigee analytics

The native tools cover the basics well; the runtime business-logic detection is still where third-party API security platforms add the most value, especially for organizations whose APIs are the product (any B2B SaaS, fintech, healthtech, marketplace).

Maturity stages

A staging model that maps to the work most programs actually do:

Stage 1 - Tribal-knowledge

APIs exist; no shared inventory. Auth is whatever each team picked. Some have rate limits; others don't. OWASP API Top 10 is something the AppSec team has read; engineering hasn't. The first breach or close call kicks off the next stage.

Stage 2 - Documented

OpenAPI specs exist for the major APIs. The auth pattern is standardized (typically OAuth + JWT through an identity provider). Rate limits are deployed on the obvious endpoints (login, password reset, search). An owner is listed for each major API.

Stage 3 - Gated

An API gateway fronts every external API; schema validation is enforced; rate limits are per-user. Authentication is centralized. BOLA tests run in CI for every endpoint. Webhook signature verification is mandatory.

Stage 4 - Observed

An API security platform watches production traffic, builds the inventory, alerts on anomalies. Shadow APIs surface within days of going live. Drift from OpenAPI specs is detected. Cross-user object access is flagged.

Stage 5 - Defended

Authorization is architecturally enforced through a central PDP (OPA / Cedar / AuthZed); BOLA is structurally impossible. Persisted queries for GraphQL; reflection disabled for gRPC; introspection scoped. The API security platform's behavioral models drive auto-block decisions on the worst patterns. The program is part of the product roadmap, not a separate audit.

Common pitfalls

Further reading

OWASP & standards

Authorization engines

Provider docs

Related CSOH pages

FAQ

Do I need an API security platform if I already have a WAF?

A WAF and an API security platform overlap on the surface and disagree underneath. A WAF inspects request payloads against signature and rule sets - SQLi, XSS, command injection, common bot patterns. It does not know what a logical user-id is, what "order #1247 belongs to user A" means, or that the same authenticated user just enumerated 8,000 customer accounts in two minutes. The OWASP API Top 10 is dominated by business-logic failures (BOLA, BFLA, BOPLA, unrestricted resource consumption) that look like perfectly legitimate traffic to a WAF. If you operate a non-trivial API, you generally need both: the WAF for layer-7 noise, the API security platform for the business-logic and inventory problems.

How is API authentication different from web-app authentication?

Web-app auth typically lands on a session cookie set after a login form; the browser carries the cookie automatically; CSRF protections and SameSite cookies manage cross-origin risk. API auth has to work for clients that aren't browsers - mobile apps, service-to-service calls, partner integrations, CI runners, IoT devices - so the credential is usually a bearer token (OAuth access token, JWT) or mutual TLS, transported in an Authorization header rather than a cookie. The hard parts shift: token issuance, scope design, key rotation, signature validation, and replay protection become the dominant concerns, with no browser-supplied default in your favor.

GraphQL vs REST - which is more secure?

Neither is inherently more secure; they fail in different shapes. REST's surface is many endpoints with structured per-endpoint controls - BOLA, BFLA, and over-fetching dominate. GraphQL's surface is one endpoint with arbitrary query shapes, so authorization has to be enforced at every field resolver, and the attacker can compose expensive queries (depth, breadth, batching) that a REST consumer would have to make as separate calls. The pragmatic answer: GraphQL needs depth/complexity limits, persisted queries in production, introspection disabled in prod, and field-level authorization. REST needs object-level checks on every read and consistent schema validation. Both need rate limiting tuned to their query economics.

What is BOLA and why does almost every API have it?

BOLA - Broken Object Level Authorization - is the bug where an endpoint correctly authenticates the caller and confirms they can call this kind of endpoint, but does not check whether the specific object referenced in the request belongs to that caller. /api/orders/1247 returns order 1247 regardless of whether the authenticated user owns it. The reason it's nearly universal: object ownership lives in business data, not in the auth middleware, so the check has to be written into every handler - and one missed handler is a complete data-disclosure bug. The defenses are architectural (scope all queries through an authorization layer that joins user-id with object-id) and detective (log every cross-user object access and alert on patterns).

Should I disable GraphQL introspection in production?

Yes for almost every internet-facing GraphQL API. Introspection lets a client query the entire schema - types, fields, arguments, deprecations - which is exactly the recon a credentialed or unauthenticated attacker uses to plan further queries. Keep introspection on in development; disable or scope it (behind an internal-only header, a feature flag, or auth role) in production. The same goes for gRPC reflection.

Is mTLS overkill for service-to-service APIs?

Not in 2026. For east-west service-to-service traffic in a Kubernetes or service-mesh environment, mTLS is now the default - Istio, Linkerd, Consul, and the managed meshes all bring it without per-app code changes. For north-south (gateway to backend, partner integrations), mTLS is heavier to operate (cert lifecycle, partner onboarding) but pays back when the data is sensitive enough that "a leaked bearer token is a breach." The decision is usually: mesh inside, OAuth/OIDC at the edge, optional mTLS at the edge for high-trust partners.

How do I find APIs I don't know exist?

Shadow APIs - endpoints that exist in production but aren't in the inventory - are the dominant API governance problem. Discovery happens three ways: from traffic (mirror or sample gateway logs, parse for distinct paths, methods, and authentication shape), from code (scan repos for route definitions in known frameworks), and from the cloud (enumerate API Gateway / APIM / Apigee resources across every account). API security platforms (Salt, Traceable, Noname/Akamai, Cequence, Wallarm) build inventory from passive traffic; CSPMs increasingly enumerate the cloud-managed APIs. The maturity goal is one inventory that combines all three sources, deduplicated, with each entry mapped to an owning team.

Where next