OpenAPI Security Schemes

OpenAPI security schemes describe how an API expects clients to authenticate, including API keys, HTTP authentication, OAuth 2.0, and OpenID Connect. They document the security mechanism and how credentials are supplied, while the actual authentication and authorization logic remains implemented by the API.

An OpenAPI `securitySchemes` component defines reusable authentication mechanisms for an API. A scheme can describe an API key supplied in a header, query parameter, or cookie; HTTP authentication such as Basic or Bearer; OAuth 2.0; or OpenID Connect.

A scheme is declared under `components.securitySchemes` and then applied with the `security` field. Applying a scheme at the root level establishes a default requirement for operations, while an operation-level `security` value can override that default.

For HTTP Bearer authentication, the scheme uses `type: http` and `scheme: bearer`. The optional `bearerFormat` field can document the expected token format, such as JWT, but it does not validate or enforce that format.

OAuth 2.0 and OpenID Connect schemes contain additional metadata. OAuth 2.0 describes supported flows and scopes; OpenID Connect points to an issuer's discovery URL. These declarations help clients and documentation tools understand the authentication contract, but they do not themselves implement token issuance, validation, or authorization.

An empty security requirement object `{}` means that an operation is explicitly available without authentication. Multiple security requirement objects in an array represent alternatives, while multiple schemes inside one security requirement object represent requirements that must be satisfied together.

Key points

Interview questions

How do you document Bearer token authentication in OpenAPI?

Define a scheme under `components.securitySchemes` with `type: http` and `scheme: bearer`. You can optionally set `bearerFormat` to something such as `JWT` to document the expected token representation. Then reference the scheme from an operation's `security` array. OpenAPI describes the contract; the server still has to validate the token.

What is the difference between `securitySchemes` and `security` in OpenAPI?

`securitySchemes` defines named, reusable authentication mechanisms under `components`. The `security` field references those names to state which mechanisms are required. A root-level `security` value can establish a default for operations, while an operation can provide its own value. Thus, one describes how authentication works and the other describes where it is required.

How does OpenAPI represent multiple authentication options?

Multiple security requirement objects in the `security` array represent alternatives. For example, one object can require an API key and another can require Bearer authentication, meaning either mechanism may satisfy the requirement. Multiple schemes inside the same security requirement object are interpreted together, representing a combined requirement. This distinction is important when documenting APIs that support several authentication methods.

What does an empty security requirement object mean?

An empty security requirement object `{}` indicates that no authentication is required for that security requirement. This is useful when an API has a global security default but a particular operation is intentionally public. At the operation level, `security: []` has a different meaning: it removes the inherited security requirements and makes the operation unauthenticated. The exact form matters when overriding global security.

What does OpenAPI actually enforce at runtime?

OpenAPI security schemes are descriptive metadata and do not themselves authenticate requests or authorize users. A Java backend still needs runtime components such as filters, authentication providers, token validation, or authorization rules. Tools can use the OpenAPI document to generate clients, documentation, or authentication configuration, but those tools do not replace server-side security enforcement. The documented contract should therefore remain consistent with the application's actual security behavior.