APIs expose business logic and data directly to software that calls them at machine speed, so the controls that protect a web page are not enough. The failures that follow are rarely exotic: most are authorization and inventory gaps that a design review or a single negative test would have caught.
This paper sets out a defender's control set framed by the OWASP API Security Top 10 and the zero trust tenets of NIST Special Publication 800-207: identity for every kind of consumer, from OAuth 2.0 grants and OpenID Connect to sender-constrained tokens and workload identity; authorization enforced at object and property level inside the service; transport and payload protection; the gateway's strengths and limits; threat protection and inventory; security built into contracts, templates, tests and secrets; monitoring and response; and a security baseline by exposure tier, with metrics and a maturity path.
Written for Security architects, API platform leads, solution architects, engineering managers and senior engineers responsible for exposing and consuming APIs safely.
Executive summary
An application programming interface (API) hands business logic and data to other software: code that can enumerate identifiers, replay requests and try every operation thousands of times a minute. The failures that follow are rarely exotic; they are authorization gaps.
This paper gives practitioners a control set framed by the Open Worldwide Application Security Project (OWASP) API Security Top 10 and the zero trust tenets of NIST Special Publication 800-207. Responsibility is shared: the gateway applies controls that are identical across APIs, the service makes the business and data decisions only it can make, and the platform supplies identities, keys, policy and telemetry.
- Identity: authorization code with Proof Key for Code Exchange (PKCE) for applications acting for users, client credentials and workload identity for machines, OpenID Connect for user identity, complete token validation, and sender-constrained tokens where theft is costly.
- Authorization: object-level and property-level decisions in the service on every request, scopes distinguished from permissions, policy as code, and end-user context carried by token exchange.
- Edge and threat protection: Transport Layer Security (TLS) on every hop, a gateway that offloads authentication, validation, limits and abuse protection, and defenses against resource abuse, business-flow abuse, server side request forgery and forgotten APIs.
- Assurance and governance: threat modeling, security in the OpenAPI contract, authorization tests and secret scanning in the pipeline, logs without tokens, rehearsed revocation, and a baseline by exposure tier with metrics.
The closing sections set out a security baseline by exposure tier, the metrics that show whether it holds, and a staged maturity path whose turning point is authorization enforced and tested inside the service.
Why API security is different
An API exposes operations and data to other software, with three consequences for security. The consumer is a machine, so volume, speed and repetition are limited only by its resources. The interface is documented, so an attacker reads the same contract a developer reads. And the API reaches business logic directly, often with internal identifiers in plain view. Most API breaches are therefore authorization and inventory failures, not cryptographic ones.
The OWASP API Security Top 10 as the threat frame
OWASP publishes the API Security Top 10 as a ranked list of the weaknesses most often found in APIs: a shared vocabulary rather than a complete threat model. The edition summarized here merged two entries from its predecessor, excessive data exposure and mass assignment, into broken object property level authorization, because both are failures to authorize individual properties. It also added three entries: unrestricted access to sensitive business flows, server side request forgery and unsafe consumption of APIs.
| Rank | Risk | Primary controls |
|---|---|---|
| 1 | Broken object level authorization | Ownership check on every object access; negative tests |
| 2 | Broken authentication | OAuth 2.0 and OpenID Connect; complete token validation |
| 3 | Broken object property level authorization | Explicit request and response models per role |
| 4 | Unrestricted resource consumption | Rate limits, quotas, payload and page size caps |
| 5 | Broken function level authorization | Deny by default for every operation |
| 6 | Unrestricted access to sensitive business flows | Flow-specific limits, bot detection, step-up verification |
| 7 | Server side request forgery | Destination allow-lists; blocked private address ranges |
| 8 | Security misconfiguration | Hardened templates; configuration scanning |
| 9 | Improper inventory management | Discovery, a catalog, the gateway as the only route |
| 10 | Unsafe consumption of APIs | Validate upstream data; timeouts; allow-listed hosts |
Shared responsibility and zero trust
No single component prevents all ten. The API gateway sees every request but not who owns which order; the service knows the business rules but cannot absorb a flood alone; and the platform (identity provider, secrets store, network and pipeline) supplies what both depend on. Recording, for each risk, which component is accountable exposes the controls that everyone assumes someone else owns.
Zero trust, as described in National Institute of Standards and Technology (NIST) Special Publication 800-207, adds the governing rule: no request is trusted because of where it originates, every access is authenticated and authorized against dynamic policy with least privilege, and the policy decision point that evaluates policy is separated from the policy enforcement point that applies it.
Identity for API consumers
Four consumer types prove identity differently: end users acting through an application, first-party services, partners under contract, and machines and workloads acting on their own behalf. The table at the end of this section summarizes the recommended pattern for each.
OAuth 2.0 roles and grants
OAuth 2.0 (RFC 6749) is the framework for delegated access. Its roles are the resource owner, usually the user; the client, the application seeking access; the authorization server, which issues tokens; and the resource server, the API that accepts them. Of the grant types RFC 6749 defines, two remain the recommended workhorses: the authorization code grant, in which the user authenticates at the authorization server and the client exchanges a short-lived code for an access token, and the client credentials grant, for machine-to-machine access by a confidential client. The refresh token grant renews access, and the device authorization grant (RFC 8628) serves devices that lack a browser or a convenient keyboard.
The other two original grants are deprecated by the IETF's security guidance. The implicit grant returned access tokens in the browser's URL fragment, where they leak through history, logs and referrer headers; the resource owner password credentials grant had the client collect the user's password directly. RFC 9700, the IETF's Best Current Practice for OAuth 2.0 Security, says that clients should not use the implicit grant and that the password grant must not be used. OAuth 2.1, an IETF Internet-Draft that consolidates OAuth 2.0 with these practices, omits both grants entirely.
The authorization code grant is used with Proof Key for Code Exchange (PKCE), RFC 7636: the client generates a random code verifier, sends its SHA-256 hash as a code challenge with the authorization request (the S256 method) and presents the verifier when it redeems the code, so that an intercepted code is useless to anyone else. RFC 9700 requires PKCE for public clients and recommends it for confidential clients, and the OAuth 2.1 draft requires it for all clients, with narrow exceptions. Its companion rule is exact string matching of registered redirect URIs, which stops attackers from exploiting loose pattern matching to have codes and tokens delivered to URIs they control. The figure below traces the full exchange.
- User and browser
- Client application
- Authorization server
- API (resource server)
OpenID Connect for user identity
OAuth 2.0 authorizes; it does not say who the user is. OpenID Connect (OIDC) Core 1.0, from the OpenID Foundation and also published as ISO/IEC 26131, adds the identity layer: the authorization server returns an ID token, a signed JSON Web Token describing the authentication event and the user, alongside the access token. The ID token is for the client; the access token is for the API. An API that accepts ID tokens as access credentials confuses the two, and accepts tokens whose audience is the client rather than itself.
Validating tokens
A JSON Web Token (JWT), RFC 7519, is a compact, signed set of claims that a resource server can validate locally. RFC 8725, the JWT Best Current Practices, sets out what complete validation means: verify the signature with a key from a trusted source and accept only an allow-listed set of algorithms, rather than whatever the token's header names (and never none); check the issuer and the audience; enforce expiry; and use explicit typing so that one kind of token cannot be substituted for another, as the JWT profile for OAuth 2.0 access tokens (RFC 9068) does with the at+jwt type. Signing keys come from the issuer's published key set, located through authorization server metadata (RFC 8414) or OpenID Connect discovery, cached, and refreshed when an unknown key identifier appears.
// Header
{ "typ": "at+jwt", "alg": "ES256", "kid": "signing-key-7" }
// Claims
{
"iss": "https://login.example.com",
"aud": "https://api.example.com/claims",
"sub": "u-8c41f2",
"client_id": "broker-portal",
"scope": "claims.read",
"jti": "a1f3e9c0",
"iat": <issue time>,
"exp": <issue time plus five minutes>,
"cnf": { "jkt": "<thumbprint of the client's DPoP key>" }
}
The decoded access token above shows what the API checks: the type and an allow-listed algorithm in the header, the issuer and audience it expects, a lifetime measured in minutes, and a confirmation claim that binds the token to a key the client holds. Opaque tokens, which carry no readable claims, are checked instead through the authorization server's introspection endpoint (RFC 7662), trading a call per request (often cached for a few seconds) for revocation that takes effect almost at once.
Lifetimes, refresh and sender constraint
The usual design pairs a short-lived access token, valid for minutes, with a longer-lived refresh token that the client presents to the authorization server for a new access token. RFC 9700 requires refresh tokens issued to public clients to be either sender-constrained or rotated. With rotation, every use returns a new refresh token, and reuse of an old one signals theft and revokes the whole token family. RFC 7009 defines a revocation endpoint through which a client can invalidate its tokens before they expire, for example when a user signs out.
A bearer token (RFC 6750) grants access to whoever presents it. A sender-constrained token is bound to a key the client holds, and the client proves possession of that key on each use, so a stolen token is useless on its own. Mutual TLS client authentication and certificate-bound access tokens (RFC 8705) record a thumbprint of the client certificate in the token, which the resource server matches against the certificate presented on the TLS connection. Demonstrating Proof of Possession (DPoP), RFC 9449, binds at the application layer instead: the client signs a short-lived proof for each request covering the HTTP method, the target URI and a hash of the access token. Mutual TLS suits partners and services that already manage certificates; DPoP suits mobile and other public clients for which client certificates are impractical.
Browser applications need extra care, because anything a browser holds can be reached by malicious script running in the page. RFC 10017, the IETF's best current practice for browser-based applications, ranks a backend for frontend as the most secure pattern: a server-side component acts as a confidential client, keeps tokens out of the browser entirely and relies on a hardened session cookie, and the document strongly recommends it for business applications and for applications that handle sensitive or personal data. Where the browser must hold tokens itself, sender-constraining them with DPoP limits the value of a stolen token, though not the damage that script running in the page can do.
For APIs where the stakes justify a formal profile, such as open banking and other high-value financial services, the OpenID Foundation's FAPI 2.0 Security Profile packages these measures into one testable baseline: pushed authorization requests (RFC 9126), PKCE with the S256 method, confidential clients only, authenticated by mutual TLS or a signed JWT, and sender-constrained access tokens only, by mutual TLS or DPoP. Conformance tests and certification are available for authorization servers and clients, which makes the profile a practical requirement to write into partner contracts.
API keys and workload identity
An API key, a long-lived static secret, identifies and meters an application, but it is not strong authentication: it does not expire, is not bound to a sender and leaks easily through code, logs and screenshots. OAuth 2.0 or mutual TLS is added wherever data is sensitive, and the key is kept for identification and quota.
Services need identities of their own. Workload identity gives each running workload a short-lived, verifiable credential derived from the platform's attestation of what it is, replacing shared secrets in configuration. SPIFFE (the Secure Production Identity Framework for Everyone), a Cloud Native Computing Foundation (CNCF) project, is one example: it issues uniform identifiers and short-lived X.509 or JWT identity documents that service meshes use for mutual TLS. Cloud platforms offer equivalent managed identities for the workloads they host.
| Consumer type | Recommended pattern | Avoid |
|---|---|---|
| End user through an application | Authorization code with PKCE; OIDC; refresh rotation or sender constraint; a backend for frontend for browser applications | Implicit and password grants; long-lived tokens in browser storage |
| First-party service | Workload identity with mutual TLS; token exchange for user context | Shared secrets; forwarded front-door tokens |
| Partner system | Client credentials with mutual TLS or a signed JWT assertion; FAPI 2.0 for high-value APIs | An API key as the only credential |
| Machine, device or batch job | Client credentials, or the device authorization grant; managed workload identity | Keys embedded in images or code |
| Public data consumer | API key for identification and quota | Treating the key as authentication |
Protecting transport and payloads
Transport protection keeps the conversation confidential and intact; payload protection covers values that stay sensitive after the transport ends, and the messages an API sends out.
TLS and the certificate lifecycle
Every endpoint, internal or external, requires Transport Layer Security (TLS) 1.2 or later, with TLS 1.3 preferred; TLS 1.3 is specified in RFC 9846, which replaced RFC 8446, and TLS 1.0 and 1.1 are deprecated (RFC 8996). Terminating TLS at a load balancer and sending plain HTTP onward reintroduces the trusted network, so traffic is re-encrypted to the service. HTTP Strict Transport Security (HSTS, RFC 6797) stops browsers from downgrading to plain HTTP.
Certificates are a lifecycle: issuance from an internal or public certificate authority, automated renewal with a protocol such as Automatic Certificate Management Environment (ACME, RFC 8555), an inventory with owners and expiry dates, and rehearsed revocation. Expired certificates remain a common cause of API outages, and the CA/Browser Forum is shortening the maximum validity of publicly trusted TLS certificates in stages, to 47 days at the end of its schedule, which makes automated renewal mandatory rather than advisable.
Field-level protection
Some values are copied beyond the transport: card numbers, national identifiers, health data. Field-level encryption encrypts individual properties under keys that intermediaries such as gateways, log pipelines and brokers do not hold. Tokenization replaces the value with a surrogate whose mapping lives in a separately controlled vault, so that most systems never hold the original; it is the standard way to shrink the footprint of systems that handle card data.
Webhooks, callbacks and replay
When the API calls out, the consumer must be able to authenticate the API. Webhooks are therefore signed: the sender computes a message authentication code over the payload and a timestamp with a per-consumer secret, or signs with a private key, and sends the result in a header. The receiver verifies the signature before parsing, rejects timestamps outside a short window to prevent replay, and treats the event identifier as an idempotency key.
What not to put in URLs and logs
URLs are copied into browser histories, proxy logs, referrer headers and tickets, so tokens, API keys, session identifiers, passwords and personal identifiers never appear in one, including the query string. RFC 6750 allowed an access token in a query parameter only as a last resort, and RFC 9700 goes further: clients must not send access tokens that way. Credentials travel in the Authorization header, or in a request body over TLS. The section on monitoring, detection and response returns to what logs must never contain.
The gateway's role and its limits
An API gateway is the managed entry point through which consumers reach APIs, applying once the controls that are identical across them: terminating TLS, authenticating callers, validating requests, enforcing limits and recording traffic. Catalog, lifecycle and security baselines all assume that production APIs are reachable only through one.
What the gateway does well
- Authentication offload. JWT signatures, issuers, audiences and expiry validated; opaque tokens introspected; client certificates checked.
- Request validation. The published OpenAPI schema enforced on paths, parameters, headers and bodies; undeclared fields and oversized payloads rejected.
- Rate limits and quotas. Applied per consumer, token, operation and plan, with 429 responses and Retry-After headers.
- Abuse protection. Bot detection and web application firewall (WAF) rules tuned to API traffic.
- Consistent telemetry. Correlation identifiers, structured access logs, and error responses that reveal nothing about the implementation.
What the gateway cannot do
A gateway cannot make business authorization decisions: it does not know that this broker may see that claim. It cannot make data-level decisions about which properties a role may read. And it does not protect the routes that bypass it: direct service-to-service calls, administrative endpoints on internal ports, message consumers and batch jobs, and retired hosts still resolving in DNS.
Edge and network
TLS, denial-of-service absorption, WAF, bot detection
API gateway
Authentication, schema validation, limits, quotas
Service
Object and property authorization, business rules
Service to service
Workload identity, mutual TLS, token exchange
Data
Tenant scoping, field encryption, least-privilege access
The figure above stacks the layers from the edge to the data, with the service, where object and property decisions are made, as the layer no other can replace. Detection and response cut across all of them: logs without secrets, per-consumer baselines and rehearsed revocation.
The network behind the gateway
The internal network is a routing fabric, not a trust boundary. Services behind the gateway authenticate each other with workload identities over mutual TLS, authorize each call as rigorously as an external one, and carry end-user context by token exchange. A service mesh can supply identity, encryption and policy enforcement for service-to-service calls through proxies that sit beside each instance or on each node; it is justified where many services in several languages need uniform policy.
Threat protection and abuse resistance
Threat protection keeps an API available and honest under hostile or careless use: limits on consumption, protection of the flows that attackers monetize, defenses against requests that turn the service into a tool, an inventory of what is reachable, and care in consuming other organizations' APIs.
Rate limiting and resource consumption
Rate limiting bounds requests per time window, throttling slows requests rather than rejecting them, and quotas cap use over a day or a billing period. Limits are keyed on several dimensions at once (per client, per user or token, per operation and per API), because a limit keyed on one dimension alone is bypassed through another. Every limit is signaled with 429 (Too Many Requests) and a Retry-After header.
Consumption is bounded beyond request counts: maximum payload sizes at the gateway, a page size clients cannot override, bounded uploads and batches, and timeouts on every downstream call. GraphQL needs depth limits, complexity scoring, introspection disabled in production for public tiers and, where clients are known, persisted queries that allow only pre-registered operations.
Sensitive business flows
Some flows are worth abusing through automation even when each individual request is legitimate: account creation, purchase of scarce stock, referral rewards, password reset. The OWASP list calls this unrestricted access to sensitive business flows. The design names the flows that would cause harm if automated, then adds proportionate controls: device and behavioral signals, step-up verification at the point of value, velocity limits keyed on business entities such as accounts, cards or delivery addresses, and alerts on business metrics.
Server side request forgery and injection
Server side request forgery (SSRF) occurs when an API fetches a caller-supplied URL and the caller points it at internal systems, including cloud metadata services that return credentials. The defenses are an allow-list of destinations, rejection of private and link-local addresses after name resolution, no automatic redirects, and network rules under which the service cannot reach sensitive hosts in the first place. Injection defenses are the familiar ones: parameterized queries, output encoding by context and schema validation.
Inventory: shadow and zombie APIs
An API nobody remembers is still reachable. Shadow APIs were never registered, such as a debugging endpoint or a mobile backend built outside the platform; zombie APIs were registered and then forgotten, such as a deprecated version or a staging host still answering. The controls are discovery from traffic, gateway logs and cloud inventories; a catalog as the single register of APIs, with an owner for each; routing that makes the gateway the only path to production; and retirement that blocks traffic and removes credentials. An API outside the catalog is an unassessed risk.
Safe consumption of third-party APIs
The organization's services are consumers too, and the OWASP list closes with unsafe consumption: data from a vendor or partner API trusted as if it were internal. External responses are validated against a schema before use and treated as untrusted input wherever they flow next. Timeouts, retry budgets and circuit breakers bound what a failing upstream can do; redirects are followed only to allow-listed hosts; and upstream credentials live in the secrets manager.
Building security in
Controls added after an API is live are the most expensive kind. Each API should arrive with its threat model, its security requirements in the contract, secure defaults and tests that prove them, all enforced by the delivery pipeline.
Threat modeling for APIs
Threat modeling answers four questions, in the framing Adam Shostack popularized: what are we working on, what can go wrong, what are we going to do about it, and did we do a good enough job? For an API the first answer is the contract plus a data flow diagram with trust boundaries wherever identity changes. The second comes from walking the OWASP API Security Top 10 and a framework such as STRIDE (spoofing, tampering, repudiation, information disclosure, denial of service and elevation of privilege) across each operation.
Security requirements in the contract
The OpenAPI Specification puts security requirements in the contract. Security schemes declare how the API authenticates: OAuth 2.0 flows with named scopes, OpenID Connect discovery, HTTP bearer authentication, mutual TLS (from version 3.1) or an API key. A security requirement on each operation states which scheme and scopes it needs, so an operation without one is a visible decision rather than an oversight. Schema constraints (lengths, patterns, enumerations, array bounds and a ban on additional properties) double as input validation at the gateway, and contract linting rejects an operation without a security requirement before any code exists.
components:
securitySchemes:
brokerAuth:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://login.example.com/authorize
tokenUrl: https://login.example.com/token
scopes:
claims.read: Read the claims a broker is entitled to see
paths:
/claims/{claimId}:
get:
operationId: getClaim
security:
- brokerAuth: [claims.read]
Secure templates and defaults
Teams build what the template makes easy. A golden template for a new API service ships with token validation configured against the organization's issuers, authorization middleware that denies by default, structured logging with redaction, TLS settings, scanning enabled in the pipeline, and gateway registration generated from the contract. Loosening a default is a reviewable change.
Testing
Static analysis finds injection patterns and hard-coded credentials. Dependency scanning finds known-vulnerable libraries. Secret scanning catches keys and tokens before they are committed. Dynamic testing exercises the running API with requests generated from the OpenAPI document. Authorization tests are written by hand from the threat model: that a subject cannot reach another subject's or another tenant's object, and that an ordinary role is refused every privileged operation. Their coverage is one of the security metrics, because no scanner writes them.
Secrets, penetration testing and disclosure
Every credential an API holds lives in a secrets manager and reaches the workload at runtime, never committed to a repository, baked into an image or left in an environment file. Rotation is automated and rehearsed; a secret that cannot be rotated without an outage will be exploited at the worst moment.
Penetration testing scoped to the threat model, including authorization and business-flow abuse, is scheduled by exposure tier: before launch and after material change for public and partner APIs, and on a risk-based cadence for private ones. A vulnerability disclosure policy gives researchers a safe way to report findings, and a bug bounty rewards them. Every finding feeds the threat model, the template and the linting rules.
Monitoring, detection and response
Prevention fails somewhere eventually; detection and response decide what it costs. For APIs the work is specific: logs that are useful without becoming a liability, baselines that make abuse visible, and a response plan whose first moves are revocation and rotation.
Security logging
Every request produces a structured record at the gateway and in the service, correlated by a request identifier: timestamp, operation and version, client identifier, a pseudonymous subject identifier, tenant, source address, status, and the outcome of authentication and authorization decisions. Denials are logged with their reason; a burst of denials for one subject signals enumeration. Logs go to a store that the service's administrators cannot alter.
Some things never appear in a log: access, refresh and ID tokens; API keys; secrets of any kind; personal data beyond what the record needs; and full card or account numbers. The logging library redacts them by default rather than relying on every developer to remember.
Baselines, alerting and audit trails
Attacks look like traffic, so detection depends on knowing what is normal for each consumer. A per-consumer baseline records the operations a client calls, its volume and timing, the objects it touches and its error rates. Departures then mean something: a client that only ever read starting to export; a rise in 401, 403 or 404 responses; sequential identifier access. Detection rules combine gateway telemetry with authorization decisions, since authorized access at unusual scale produces no errors at all.
Alerts route to the API owner for business anomalies and to security operations for security events, with runbooks whose first actions are to block the consumer and revoke its tokens. Audit trails answer a different question: who was granted which scope, role or permission, by whom and when, and which keys were issued and rotated. They are immutable and reconciled with the catalog.
Incident response for APIs
API incidents have a characteristic shape: a credential, token or key is exposed, or an authorization flaw is found, and the exposure must be closed without taking every consumer down.
- Contain. Block or throttle the consumer at the gateway, and disable the client registration or the flawed operation.
- Revoke. Revoke the affected tokens, rotate signing keys and republish the key set, and rotate exposed keys, secrets and certificates.
- Assess. Use access logs, authorization decisions and baselines to establish which objects and tenants were reached, when and by whom.
- Notify. Tell affected consumers what to do, and engage privacy and legal functions where personal data was involved.
- Learn. Add the flaw to the threat model, write the test that would have caught it, and record the time to revoke.
Time to revoke, the elapsed time from the decision to revoke until a token, key or client no longer works anywhere, depends on token lifetimes, revocation propagation and the automation of key rotation. Forensic readiness is the other capability: logs that identify subject and object, retained long enough and protected from tampering.
Governance, compliance and the maturity path
Governance turns the controls above into a baseline that every API meets, proportionate to its exposure and to the sensitivity of its data. The baseline is enforced in the pipeline and at the gateway, and departures from it go through a recorded, time-limited exception.
A security baseline by exposure tier
Three exposure tiers are common: private APIs serve internal consumers, partner APIs serve named organizations under contract, and public APIs serve any registered developer. Every tier meets the full baseline for authentication, authorization in the service and logging. Exposure raises client authentication strength, abuse protection and assurance, and data sensitivity raises them again regardless of tier.
| Control area | Private | Partner | Public |
|---|---|---|---|
| Authentication and tokens | OAuth 2.0 or workload identity; short-lived tokens | Client credentials with mutual TLS; certificate-bound tokens; FAPI 2.0 for high-value APIs | Authorization code with PKCE; refresh rotation; DPoP or a backend for frontend |
| Authorization | Object and property checks; tests on every build | Plus per-partner data scoping | Plus step-up verification for sensitive flows |
| Transport and payload | TLS 1.2 or later on every hop | TLS 1.3 preferred; field encryption | TLS 1.3 preferred; HSTS; tokenized card data |
| Gateway controls | Schema validation; baseline rate limits | Quotas per partner; WAF | Bot protection; abuse detection; strict quotas |
| Testing and assurance | Pipeline scans; authorization tests | Plus a penetration test before launch | Plus recurring tests; a disclosure policy or bounty |
| Logging and detection | Structured logs without secrets | Plus per-partner baselines and alerting | Plus real-time abuse alerts |
Classification, minimization and regulated data
Each property in the contract is classified under the organization's data classification scheme, so that personal, confidential and regulated fields are visible to reviewers and to policy engines. Data minimization follows: an API returns the properties its consumers need for the stated purpose and no more, with purpose, lawful basis and retention recorded wherever personal data is processed.
Card data brings the Payment Card Industry Data Security Standard (PCI DSS) into scope for every component that stores, processes or transmits it, gateways and logs included. The practical response is to keep card data out of as many components as possible by tokenizing it at capture.
Metrics
| Metric | What it measures |
|---|---|
| APIs behind managed gateways | Share of production APIs reachable only through a managed gateway |
| Authorization test coverage | Share of APIs with negative object-level and function-level tests on every build |
| Token lifetime compliance | Share of clients and APIs within the lifetime and rotation policy |
| Time to revoke | Elapsed time until a revoked credential stops working everywhere |
| Findings per release | Security findings by severity, with time to fix |
| Deprecated authentication in use | Consumers still using API keys alone, the implicit or password grants, or basic authentication |
Pitfalls
A staged maturity path
- Stage 1
Perimeter
Gateway, TLS and API keys; little inside
- Stage 2
Standardized identity
OAuth 2.0 and OIDC everywhere; keys retired as credentials
- Stage 3
Authorized in the service
Object and property checks; tests in the pipeline
- Stage 4
Zero trust inside
Workload identity, mutual TLS, token exchange
- Stage 5
Measured and adaptive
Baselines, metrics, policy as code, bug bounty
The stages build on one another. Standardized identity replaces keys with OAuth 2.0, OpenID Connect and workload identity. Authorization in the service, the turning point highlighted in the figure, puts object and property checks in a shared layer tested on every build. Zero trust inside extends identity and token exchange to service-to-service calls. The measured stage adds baselines, policy as code and metrics by tier.
Conclusion
API security is less a matter of cryptography than of discipline about three questions asked on every request: who is calling, what may they do with this object and these properties, and is this traffic what this consumer normally does? Standards answer the first; only the service can answer the second; and only logging designed for the purpose can answer the third. Organizations that enforce authorization in the service and build security into the contract and the pipeline will find the OWASP list a checklist of controls they already have.
The place to begin is the authorization test the current APIs would fail.
- Write the failing test. For the most exposed APIs, add negative tests that request another user's and another tenant's objects with a valid token, and fix what they find in a shared data-access layer.
- Inventory and route. Discover every reachable API from traffic and cloud inventories, register each in the catalog with an owner, and make the managed gateway the only path to production.
- Retire weak authentication. Move remaining implicit-grant, password-grant and key-only consumers to authorization code with PKCE, client credentials or workload identity.
- Validate tokens completely. Check signature, algorithm, issuer, audience, expiry and type everywhere, shorten lifetimes, and sender-constrain tokens where theft would be costly.
- Rehearse revocation. Practice revoking tokens and rotating keys and secrets, and measure the time to revoke against a target.
Validate at the edge, authorize in the service, and trust nothing because of where it came from.
Glossary
- API key
- A long-lived static secret identifying an application; useful for quotas, not a substitute for authentication.
- Authorization code grant with PKCE
- The OAuth 2.0 grant in which the client redeems a short-lived code, bound by a proof key, for tokens after the user authenticates.
- Broken object level authorization (BOLA)
- Failing to check, on each access, that the caller may act on the specific object identified in the request.
- Confused deputy
- A privileged component that acts at a less privileged caller's request using its own authority rather than the caller's.
- DPoP
- Demonstrating Proof of Possession (RFC 9449): binding an access token to a client key through a signed proof sent with each request.
- FAPI 2.0 Security Profile
- An OpenID Foundation profile of OAuth 2.0 for high-value APIs that requires pushed authorization requests, PKCE, strong client authentication and sender-constrained tokens.
- JSON Web Token (JWT)
- A compact, signed set of claims (RFC 7519), validated locally by checking signature, algorithm, issuer, audience, expiry and type.
- Mutual TLS (mTLS)
- Transport Layer Security in which both parties present certificates, used for client authentication and certificate-bound tokens.
- OpenID Connect (OIDC)
- The identity layer on top of OAuth 2.0, in which the authorization server issues an ID token describing the authenticated user to the client.
- Policy decision point (PDP)
- The component that evaluates access policy; it is kept separate from the policy enforcement point that applies the decision.
- Scope
- A string an OAuth 2.0 client requests and the user grants, bounding what the application may ask for on the subject's behalf.
- Sender-constrained token
- An access token bound to a key held by the legitimate client, through mutual TLS or DPoP, so that a stolen token cannot be used on its own.
- Server side request forgery (SSRF)
- Inducing a service to fetch a caller-supplied URL and thereby reach internal systems.
- Token exchange
- The OAuth 2.0 mechanism (RFC 8693) by which a service trades the token it received for a narrower token addressed to the next service.
- Workload identity
- A short-lived, verifiable credential issued to a running workload on the basis of platform attestation, replacing shared secrets.
References and further reading
- OWASP Foundation, OWASP API Security Top 10; and OWASP Application Security Verification Standard (ASVS).
- IETF RFC 6749, The OAuth 2.0 Authorization Framework; RFC 6750, Bearer Token Usage; and RFC 7636, Proof Key for Code Exchange by OAuth Public Clients.
- IETF RFC 9700, Best Current Practice for OAuth 2.0 Security (BCP 240); and the Internet-Draft The OAuth 2.1 Authorization Framework.
- IETF RFC 7519, JSON Web Token (JWT); RFC 8725, JSON Web Token Best Current Practices; and RFC 9068, JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens.
- IETF RFC 7662, OAuth 2.0 Token Introspection; RFC 7009, OAuth 2.0 Token Revocation; and RFC 8693, OAuth 2.0 Token Exchange.
- IETF RFC 8705, OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens; and RFC 9449, OAuth 2.0 Demonstrating Proof of Possession (DPoP).
- IETF RFC 10017, OAuth 2.0 for Browser-Based Applications.
- OpenID Foundation, OpenID Connect Core 1.0 (also published as ISO/IEC 26131); and FAPI 2.0 Security Profile.
- IETF RFC 9846, The Transport Layer Security (TLS) Protocol Version 1.3; and RFC 8996, Deprecating TLS 1.0 and TLS 1.1.
- National Institute of Standards and Technology, Special Publication 800-207, Zero Trust Architecture; and Special Publication 800-63-4, Digital Identity Guidelines.
- Norm Hardy, The Confused Deputy (or why capabilities might have been invented), ACM SIGOPS Operating Systems Review.
- Adam Shostack, Threat Modeling: Designing for Security, Wiley.
- Neil Madden, API Security in Action, Manning Publications.
This paper offers general guidance and is not legal, regulatory or professional advice. Summaries of laws, regulations and standards are for orientation only; confirm the obligations that apply to your organization with qualified advisors. Product and vendor names are used for illustration and imply no endorsement.
© ByteCI, LLC. All rights reserved.