API security
Protecting the APIs that programs use to talk to each other, so each caller can reach and change only what it is allowed to.
Draft - this entry has not been reviewed yet.
Formal
The set of controls that guard an API - authentication of every caller, authorization checked per object and per action, limits on how often and how much can be requested, input validation and an up-to-date list of every API in use.
In plain English
Like a bank cashier who checks not only who you are but also that the account you ask about is really yours - every single time.
In practice
A municipality's citizen app asks its API for case 1001, which belongs to the logged-in citizen; a curious user changes the number to 1002 and sees a neighbour's case, because the API checked the MitID login but not who owns the case.
Why it matters
Apps, partners and AI agents increasingly reach data through APIs rather than web pages, so one missing ownership check can expose every record in a system at once.
How to put it into practice
The usual steps, in order. Adapt them to your organisation.
- Build an inventory of every API, version and environment from gateway logs and the code, and keep an OpenAPI description for each API in its repository.
- Require authentication on every endpoint by default, with OAuth 2.0 access tokens or mutual TLS, and validate the signature, issuer, audience and expiry of every token.
- Check authorisation for every object and every function inside the service, through one shared policy layer, so a caller can only read or change the records it owns.
- Return only the fields the client needs, and bind incoming bodies to explicit objects so callers cannot read or set fields such as ownerId or isAdmin.
- Set rate limits per identity, maximum page and body sizes and timeouts, and protect sensitive business flows such as sign-up or checkout against automated abuse.
- Validate requests against the OpenAPI schema at the gateway and in the service, and reject unknown content types, methods and properties.
- Test every release with two accounts in different roles to find broken object and function level authorisation, which scanners using one account rarely find.
- Log access decisions and anomalies to the SIEM, and retire old API versions on a published schedule instead of leaving them reachable.
Common pitfalls
- Trusting the API gateway or WAF to know who owns which record, although only the service itself can check that.
- Leaving old versions such as /v1 or test endpoints reachable after the new version is live.
- Treating an API key as proof of which user is calling, when it only identifies the client application.
- Accepting JWTs without checking the algorithm, audience and expiry.
Good guides
- OWASP Top 10 API Security Risks - 2023(opens in a new tab) · OWASP
- OWASP Cheat Sheet Series - REST Security(opens in a new tab) · OWASP
- NIST SP 800-228 - Guidelines for API Protection for Cloud-Native Systems(opens in a new tab) · NIST
- Securing HTTP-based APIs(opens in a new tab) · NCSC UK
- Retningslinjer for webservices(opens in a new tab) · Digitaliseringsstyrelsen (in Danish)
Technical deep dive
API security differs from classic web security because an API exposes the application's object model directly: identifiers, field names and operations arrive as structured parameters that a client can enumerate and replay at machine speed, with no user interface to hide anything. The OWASP API Security Top 10 (2023) reflects this. Its first entry, API1 Broken Object Level Authorization (BOLA, the API name for IDOR), is the case where the server authenticates the caller but never checks that the object ID in the path or body belongs to them. API3 Broken Object Property Level Authorization covers both excessive data exposure (returning every column and filtering in the client) and mass assignment (binding an incoming JSON body straight onto a model so a caller can set fields such as isAdmin or ownerId). API5 Broken Function Level Authorization is the same failure one level up, for example a regular user calling an administrative DELETE endpoint.
Authentication for machine clients is usually OAuth 2.0 access tokens, often JWTs, or mutual TLS. Common failures are accepting unsigned tokens (alg none), not validating aud, iss and exp, confusing RS256 with HS256 so a public key is used as an HMAC secret, and long-lived bearer tokens with no binding to the client. Sender-constrained tokens (mTLS-bound per RFC 8705, or DPoP per RFC 9449) reduce the value of a stolen token. API keys identify a client application; on their own they do not authenticate a user.
Resource controls address API4 Unrestricted Resource Consumption and API6 Unrestricted Access to Sensitive Business Flows: rate limits per identity rather than per IP, maximum page sizes, request body limits, timeouts and, for GraphQL, query depth and cost limits plus disabled introspection in production. API9 Improper Inventory Management is the shadow and zombie API problem: old versions such as /v1 that stay reachable without the fixes applied to /v2. An OpenAPI description kept in the build pipeline gives both an inventory and a schema that a gateway can enforce.
An API gateway or WAF is good at coarse controls (TLS termination, token validation, quotas, schema checks), but it cannot know whether user 17 owns invoice 4711. Object-level authorization therefore has to live in the service, ideally in one central policy layer, and has to be tested with two accounts, since scanners that use one identity rarely find BOLA. NIST SP 800-228 frames the same controls for cloud-native, service-to-service APIs, where east-west traffic between microservices needs authentication just as much as the public edge.
What to learn first
Everything this builds on, foundations first.
Relationships
- Requires
- APIAuthenticationAuthorization
- Mitigates
- Data breach
- Used with
- Web application firewall (WAF)
Sources & further reading
Standards & official texts
Reference works
- OWASP API Security Top 10 (2023) · OWASP
Where this data comes from
This entry was drafted by an AI from the sources above and has not yet been checked by a person. Treat it as a starting point, and check anything important against the sources.
See the review queueSuggest a correction on GitHubThis term as JSON
Check yourself
Loading…