Skip to content
routebase
API Authentication11 chapters

Chapter 08 of 11

OpenAPI Security Schemes and Per-Endpoint Auth

Security schemes, per-operation requirements, scopes, and what consumers and agents can only learn from a specification that documents its authentication.

An API that authenticates and does not say how has made every consumer's first hour harder than it needed to be. Writing an OpenAPI security scheme is a small amount of work with an unusually wide reach, because everything downstream reads it. The rest of the document is covered in the OpenAPI guide.

The two halves

OpenAPI splits this into a definition and a requirement, and keeping those two straight makes the rest of the syntax obvious.

A security scheme defines a way to authenticate. It lives under components.securitySchemes and is named, so BearerAuth or ApiKeyAuth.

A security requirement says which of those a caller must satisfy. It appears at the top level as a default and on any operation as an override.

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
 
security:
  - BearerAuth: []          # the default for every operation

The four types

TypeCoversKey fields
httpBasic, Bearer, Digest and anything else in the HTTP authentication registryscheme, and bearerFormat as a hint
apiKeyA key in a header, a query parameter or a cookiein, name
oauth2The OAuth flows, with their endpoints and scopesflows
openIdConnectAn OpenID Connect provideropenIdConnectUrl

Two notes on the details. The bearerFormat field is documentation and not validation, so writing JWT there tells a human what to expect and changes nothing mechanically. And apiKey with in: cookie exists, and a cookie-based session is usually better described that way than pretended to be a header.

Per-operation requirements, and the empty array

The top-level security field is a default, and any operation may override it.

paths:
  /health:
    get:
      security: []                      # explicitly public
      responses: { '200': { description: OK } }
 
  /admin/users:
    get:
      security:
        - BearerAuth: [users.admin]     # this operation needs a scope
      responses: { '200': { description: OK } }

The empty array is the part people miss. Omitting security on an operation means it inherits the default, and an empty array means the operation is deliberately open. That is the difference between an endpoint somebody chose to make public and one nobody got around to securing. In a specification those two look identical unless you say so.

Alternatives against combinations

The nesting here is easy to get wrong, and getting it wrong changes the meaning of the requirement entirely.

# EITHER of these satisfies the requirement
security:
  - BearerAuth: []
  - ApiKeyAuth: []
 
# BOTH are required together
security:
  - BearerAuth: []
    ApiKeyAuth: []

A list of separate entries is a list of alternatives, and several schemes inside one entry must all be satisfied. The second form is rarer and it does appear, usually where a gateway key sits in front of a user token.

Scopes belong in the specification

An oauth2 scheme declares its flows, and each flow lists the scopes that flow can issue along with a description.

components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/authorize
          tokenUrl: https://auth.example.com/token
          scopes:
            orders.read: Read orders
            orders.write: Create and modify orders

Operations then name the scopes they need, and a consumer reads the specification to find out which scopes to request. Without this they discover it by receiving a 403 and guessing, and that is a poor first hour with your API.

Write the scope descriptions for a person who is deciding what to request. A description reading "Read orders" is useful, and one reading "orders.read scope" is not.

What reads this, and why it is worth the effort

The specification is not documentation in the sense of prose that somebody might read. It is an input to several things at once.

ConsumerWhat it does with the security definition
A documentation portalRenders which scheme each endpoint expects, and configures its try-it console
A generated clientEmits the right authentication parameter and header
A mock serverDecides whether an unauthenticated call gets a 401
A contract testKnows what to send to reach the endpoint at all
An AI agentLearns how to call your API without being told separately

The last row is the newest and it changes the calculation. An agent reading a specification with documented schemes can configure itself, and an agent reading one without them will guess, usually wrongly and sometimes confidently.

Common mistakes

A scheme defined and never referenced. It documents nothing at all, because no operation actually requires it.

No top-level default in a fully secured API. Every operation then needs its own requirement, and the one somebody forgets is silently public.

Undocumented error responses. An endpoint that can return 401 and 403 should document both, since a consumer handling them needs to know the body shape.

Scopes in the scheme but not on the operations. The specification then says which scopes exist and not which ones any particular call needs.

In Routebase

Security schemes are components in the API Designer, created once per specification under the Security section and attached to endpoints from the endpoint editor. All four OpenAPI types are supported, so http, apiKey, oauth2 and openIdConnect are all available, and each endpoint lists its assigned schemes as removable badges.

Assign to endpoints dialog with four target options and a line reading seventeen endpoints selected and seventeen already carrying the scheme.
Assignment picks all endpoints, one folder, a tag or a hand-picked set, and it says what it will touch before you confirm.

The part that saves real time is assignment at scale. Attaching a scheme to sixty endpoints one badge at a time is the kind of task people skip, and a skipped endpoint looks exactly like a deliberately public one. Assign to endpoints does it in one step with four ways to pick targets, covering all endpoints, one folder, everything carrying a tag, or a hand-picked selection. Endpoints that already carry the scheme are marked as such and never silently skipped, and a preview shows what the assignment will touch before you confirm.

The definitions then flow outward. The documentation portal renders which scheme each endpoint expects and configures its try-it console accordingly, which the API documentation guide covers from the reader's side. The mock server answers 401 where the rules gate on an auth header. Try It offers a button that adds the demo header the endpoint's schemes ask for, so the 401 path stays testable by not clicking it. Export produces standard OpenAPI 3.0, 3.1 or 3.2, so the definitions travel to any generator you use.

An agent working over MCP can add a security scheme and assign it, under the same permissions your team has. See Components for the scheme editor and Endpoints for assignment and Try It.

Frequently asked questions

What is a security scheme in OpenAPI?

A security scheme is a reusable definition of one way to authenticate against your API, declared once under components and referenced from operations. OpenAPI 3 supports four types. Those are http for schemes such as Basic and Bearer, apiKey for a key in a header, query parameter or cookie, oauth2 with its flows and scopes, and openIdConnect with a discovery URL. Documenting them is what lets a client, a code generator or an agent configure itself without asking anyone.

How do you specify authentication per endpoint in OpenAPI?

A top-level security field sets the default requirement for the whole API, and any operation can override it with its own security field. An operation with an empty security array is explicitly public, and that is the only way to say a specific endpoint needs no credential when a global default exists. Being explicit matters, because an endpoint nobody remembered to secure looks identical to one that is deliberately open.

How are OAuth scopes documented in OpenAPI?

The oauth2 security scheme declares its flows, and each flow lists the scopes it can issue with a human-readable description. An operation then names the scopes it requires when it references that scheme. The result tells a consumer exactly which scopes to request for the calls they intend to make, instead of leaving them to discover it by receiving a 403.

Why document authentication in the API specification at all?

Because every consumer otherwise has to be told separately, and the telling drifts from the truth. A documented scheme drives the try-it console in your portal, the generated client, the mock server behaviour and any agent that reads the specification. It also makes an unsecured endpoint visible, since an operation with no security requirement in an otherwise secured API stands out in review.

Last reviewed by The Routebase Team.

Ready to ship on it?

Routebase is live. Design your API once — docs, mocks, tests, and monitoring all follow from the same source.

14-day Pro trial — no credit card required.