From 140dfdadf4e6316e31151afa05bbe24ee3dfb891 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Fri, 23 May 2025 18:33:39 +0100 Subject: [PATCH 01/10] style guide tweaks --- openapi/schemas/enums.md | 22 +++++++++++----------- openapi/schemas/null.mdx | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openapi/schemas/enums.md b/openapi/schemas/enums.md index c6fc7d9f..c3c4f4c3 100644 --- a/openapi/schemas/enums.md +++ b/openapi/schemas/enums.md @@ -78,7 +78,7 @@ paths: If you use `default`, remember to omit `required: true` from the field. -## Enums With Names and Values +## Enums with names and values A common requirement using enums is to specify a human-readable name for the enum label and an integer for the enum value. For example, in C#: @@ -196,9 +196,9 @@ components: description: Small Medium Large ``` -## Constants for Single Value Enums +## Constants for single value enums -Before JSON Schema 2019 was included in OpenAPI 3.1, using an enum with a single value was the only way to specify a constant. If you are still using OpenAPI 3.0, the example below shows how to specify that a constant string is returned in a response: +Before JSON Schema 2019 was included in OpenAPI v3.1, using an enum with a single value was the only way to specify a constant. If you are still using OpenAPI v3.0, the example below shows how to specify that a constant string is returned in a response: ```yaml openapi: 3.0.0 @@ -219,7 +219,7 @@ paths: - Here is your beverage ``` -When using OpenAPI 3.1, you can use the `const` keyword whose name more clearly matches its intention than `enum` does: +When using OpenAPI v3.1, you can use the `const` keyword whose name more clearly matches its intention than `enum` does: ```yaml openapi: 3.1.0 @@ -239,11 +239,11 @@ paths: const: Here is your beverage ``` -## Nullable Enums +## Nullable enums -### OpenAPI 3.0 +### OpenAPI v3.0 -In OpenAPI 3.0 you can use the `nullable` keyword to specify `null` as an accepted value in an enum. In the example below, a client can order a drink with one of three cup sizes or no cup size specified at all: +In OpenAPI v3.0 you can use the `nullable` keyword to specify `null` as an accepted value in an enum. In the example below, a client can order a drink with one of three cup sizes or no cup size specified at all: ```yaml # !focus(6) @@ -259,9 +259,9 @@ components: - LARGE ``` -### OpenAPI 3.1 +### OpenAPI v3.1 -OpenAPI 3.1 more closely aligns with the JSON Schema standard. As a result, the way to specify nullable types differs from OpenAPI 3.0. Instead of using the `nullable` attribute, OpenAPI 3.1 uses the JSON Schema approach with an array of types - including the `null` type. Here's the same example adapted for OpenAPI 3.1: +OpenAPI v3.1 more closely aligns with the JSON Schema standard. As a result, the way to specify nullable types differs from OpenAPI 3.0. Instead of using the `nullable` attribute, OpenAPI v3.1 uses the JSON Schema approach with an array of types - including the `null` type. Here's the same example adapted for OpenAPI v3.1: ```yaml # !focus(5,10) @@ -277,7 +277,7 @@ components: - null ``` -## Open Enums +## Open enums Traditionally enums are closed, meaning that only the values listed in the enum are allowed. In contrast, open enums allow additional values beyond those explicitly defined in the spec. Open Enums are useful when your API is evolving to support new use cases. In that scenario, you can let clients send values that aren't defined yet because their usage is on the edge of your API's capabilities. @@ -349,7 +349,7 @@ components: Date objects are not directly supported. Export your dates to ISO strings before using them in an API. -## Best Practices +## Best practices Enums are simple, so there are only a few things to consider when using them in your schema: diff --git a/openapi/schemas/null.mdx b/openapi/schemas/null.mdx index d72d9ebb..e4ffeaf6 100644 --- a/openapi/schemas/null.mdx +++ b/openapi/schemas/null.mdx @@ -42,9 +42,9 @@ schema: nullable: true ``` -## OpenAPI 3.1.X +## OpenAPI v3.1 -OpenAPI 3.1 aligned describing `null` with JSON Schema. This allows for more precise API definitions, especially for APIs that need to explicitly support null values as valid inputs or outputs. +OpenAPI v3.1 aligned describing `null` with JSON Schema. This allows for more precise API definitions, especially for APIs that need to explicitly support null values as valid inputs or outputs. To specify that a property, item, or response can be `null`, you can use the `type` keyword with a value of `null` or combine null with other types using the `oneOf` or type array syntax. This flexibility makes it easier to accurately model your data. From 90b3b368e5d6c889d4b1221e34b176a78386bcae Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Fri, 23 May 2025 18:39:44 +0100 Subject: [PATCH 02/10] first pass at improving security section seems to be some duplication on index.mdx so removed for now. need to properly seperate and cross link security schemes vs requirements. --- openapi/security.mdx | 16 +- openapi/security/security-schemes.md | 109 ++++++++----- openapi/security/security-schemes/index.mdx | 117 -------------- .../security-schemes/security-basic.mdx | 40 ----- .../security-schemes/security-bearer.mdx | 40 ----- .../security-schemes/security-http.mdx | 150 ++++++++++++++++++ .../security-schemes/security-mutualtls.mdx | 49 ++++++ 7 files changed, 275 insertions(+), 246 deletions(-) delete mode 100644 openapi/security/security-schemes/index.mdx delete mode 100644 openapi/security/security-schemes/security-basic.mdx delete mode 100644 openapi/security/security-schemes/security-bearer.mdx create mode 100644 openapi/security/security-schemes/security-http.mdx create mode 100644 openapi/security/security-schemes/security-mutualtls.mdx diff --git a/openapi/security.mdx b/openapi/security.mdx index 1b77e5bc..009d9cbc 100644 --- a/openapi/security.mdx +++ b/openapi/security.mdx @@ -31,7 +31,7 @@ components: in: header ``` -In valid OpenAPI 3.1, the [Security Requirement Objects](/openapi/security#security-requirement-object) listed in `security` sections may only reference [Security Scheme Objects](/openapi/security/security-schemes) that are defined in the [Components Object](/openapi/components) under the `securitySchemes` field. In other words, the `security` section may not contain inline security schemes, and it may not contain security schemes that are not defined yet. +In valid OpenAPI v3.1, the [Security Requirement Objects](/openapi/security#security-requirement-object) listed in `security` sections may only reference [Security Scheme Objects](/openapi/security/security-schemes) that are defined in the [Components Object](/openapi/components) under the `securitySchemes` field. In other words, the `security` section may not contain inline security schemes, and it may not contain security schemes that are not defined yet. ## Security Requirement Object @@ -53,15 +53,13 @@ A Security Requirement Object defines a map of security scheme names to [scopes Before referencing a [Security Scheme](./security/security-schemes.md) as a requirement in the `security` section, it must be defined in the [Components Object](/openapi/components) under the `securitySchemes` field. -OpenAPI 3.1 supports the following security schemes: +OpenAPI v3.1 supports the following security schemes: -- [API Key](./security/security-schemes/security-api-key.md) -- [Basic HTTP](./security/security-schemes/security-basic.md) -- [Bearer Token](./security/security-schemes/security-bearer.md) -- [OAuth 2.0](./security/security-schemes/security-oauth2.md) -- [OpenID Connect](./security/security-schemes/security-openid.md) -- Digest -- Mutual TLS +- [API Key](/openapi/security/security-schemes/security-api-key) +- [HTTP Authorization](/openapi/security/security-schemes/security-basic) (E.g: Basic, Digest, Bearer, and more) +- [OAuth 2.0](/openapi/security/security-schemes/security-oauth2) +- [OpenID Connect](/openapi/security/security-schemes/security-openid) +- [Mutual TLS](/openapi/security/security-schemes/security-mutualtls) ## Expressing Security Requirements in OpenAPI diff --git a/openapi/security/security-schemes.md b/openapi/security/security-schemes.md index b1e18563..0d149965 100644 --- a/openapi/security/security-schemes.md +++ b/openapi/security/security-schemes.md @@ -1,117 +1,146 @@ --- -title: "Security Schemes in OpenAPI best practices" -description: "Implement secure API authentication using Security Schemes in your OpenAPI specification for better security, developer experience, and seamless integration." +title: "Security Schemes in OpenAPI" +description: "Describe API authentication and authorization in OpenAPI using Security Schemes." --- -# Security Scheme Objects in OpenAPI +# Security Schemes in OpenAPI -Security scheme objects are defined in the [Components Object](/openapi/components) under the `securitySchemes` field. Each security scheme object has a unique key. [Security Requirement Objects](/openapi/security#security-requirement-object) elsewhere in the document reference security scheme objects by their keys. +Most APIs have some form of authorization and/or authentication, from simple API keys to scope-based OAuth 2 tokens on a tight rotation. APIs might support multiple methods in various combinations, so describing what goes where can become a bit of a challenge. OpenAPI helps by supporting a wide array of authorization and authentication methods, all of which can described under the larger umbrella of Security Schemes. -The following example requires a basic authentication scheme to access the `/drinks` endpoint: +Security scheme objects are defined in the [Components Object](/openapi/components) in the `securitySchemes` section, and the `security` field in the root object or operation object references them. The `security` field is an array of security requirement objects, which are maps of security scheme names to scopes. ```yaml paths: /drinks: get: security: - - MyScheme17: [] + - MySchemeAbc: [] components: securitySchemes: - MyScheme17: + MySchemeAbc: type: http scheme: basic ``` -The `type` field is the overall category of authentication. The value of `type` determines the other fields the security object needs. +Each security scheme has a unique name in the `securitySchemes` map, and the `type` field is particular standard or convention. -To decide which authentication type to choose, see our article [OpenAPI Tips - How to Handle Auth](/post/openapi-tips-auth). +## Authentication Types -## OpenAPI-Supported Authentication Types - -The following authentication types are supported in the OpenAPI Specification: +The following authentication types are supported by OpenAPI as of v3.1: - [API Key](/openapi/security/security-schemes/security-api-key) -- [Basic HTTP](/openapi/security/security-schemes/security-basic) -- [Bearer Token](/openapi/security/security-schemes/security-bearer) +- [HTTP Authorization](/openapi/security/security-schemes/security-basic) (E.g: Basic, Digest, Bearer, and more) - [OAuth 2.0](/openapi/security/security-schemes/security-oauth2) - [OpenID Connect](/openapi/security/security-schemes/security-openid) -- Digest -- Mutual TLS +- [Mutual TLS](/openapi/security/security-schemes/security-mutualtls) ## OpenAPI Example Security Scheme Schema -Below is an example security schemes object with every possible field besides extensions. +Here's an example security schemes object with the sort of values likely to be used. The names are arbitrary and just used for clarity, but could be whatever you want. ```yaml components: securitySchemes: # apiKey ------------ - auth1: - description: Recommended authenticator + ApiKeyInQuery: type: apiKey in: query name: key - auth2: + ApiKeyInCustomHeader: type: apiKey in: header - name: X-API-Key + name: Acme-API-Key - auth3: + ApiKeyInCookie: type: apiKey in: cookie name: key # http ------------ - auth4: + HttpBasic: type: http scheme: basic - auth5: + HTTPDigest: type: http - scheme: bearer - bearerFormat: JWT + scheme: digest # not supported by Speakeasy - auth6: + JWT: type: http - scheme: digest # not supported by Speakeasy + scheme: bearer + bearerFormat: JWT # mutualTLS ------------ - auth7: + MutualTLS: type: mutualTLS # not supported by Speakeasy # openIdConnect ------------ - auth8: + OpenId: type: openIdConnect openIdConnectUrl: https://example.com/openidconfig.json # oauth2 ------------ - auth9: + OAuth2: type: oauth2 flows: authorizationCode: scopes: read: Grants read access write: Grants write access - authorizationUrl: https://test.com/oauth/authorize - tokenUrl: https://test.com/oauth/token - refreshUrl: https://test.com/oauth/refresh + authorizationUrl: https://example.org/oauth/authorize + tokenUrl: https://example.org/oauth/token + refreshUrl: https://example.org/oauth/refresh clientCredentials: scopes: read: Grants read access write: Grants write access - tokenUrl: https://test.com/oauth/token - refreshUrl: https://test.com/oauth/refresh + tokenUrl: https://example.org/oauth/token + refreshUrl: https://example.org/oauth/refresh implicit: scopes: read: Grants read access write: Grants write access - authorizationUrl: https://test.com/oauth/authorize - refreshUrl: https://test.com/oauth/refresh + authorizationUrl: https://example.org/oauth/authorize + refreshUrl: https://example.org/oauth/refresh password: scopes: read: Grants read access write: Grants write access - tokenUrl: https://test.com/oauth/token - refreshUrl: https://test.com/oauth/refresh + tokenUrl: https://example.org/oauth/token + refreshUrl: https://example.org/oauth/refresh ``` + +To learn more about different types of security scheme, take a look at the guides for [API Key](/openapi/security/security-schemes/security-api-key), [HTTP Authorization](/openapi/security/security-schemes/security-basic) (Basic, Digest, Bearer, and more), [OAuth 2.0](/openapi/security/security-schemes/security-oauth2), [OpenID Connect](/openapi/security/security-schemes/security-openid), or [Mutual TLS](/openapi/security/security-schemes/security-mutualtls). + + +## Global authentication vs endpoint authentication + +Describing security in your OpenAPI document is then done through 1 of 2 different options: + +- **Global security:** the security you describe is available for all operations in your document. +- **Per operation security:** when described it overrides any global level security described. + +Here is an example of describing security in the ways mentioned above: + +The important parts of the above example are the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) and [securitySchemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object/security-schemes) sections. We will go into some details about how they are defined and the options available. + +## How to describe security + +The [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section is a list (actually a list of key-value pairs, but we will talk a bit more about that later) of security schemes that can be used to authenticate all operations or a particular operation (depending on the scope of the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) list). + +Below is an example of a number of different ways you can use the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section of your document: + +The items in the list are key-value pairs with a name or key of a security scheme defined in the components section. We recommend giving them a boring name that explains what they are. + +The values are an array of scopes used only by the [oauth2](https://spec.openapis.org/oas/v3.1.0#oauth2-security-requirement) and [openIdConnect](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06) type schemes, and define what scopes are needed for the API. + +When used as shown above it provides a list of available schemes that can be used, with the end-user of the API being able to choose one of the available schemes to use to authenticate. + +If more than one scheme is required to authenticate an API, then that is where additional pairs in the key-value pairs come in. See the example below: + +Combining schemes like above give you the option to define AND/OR type functionality when it comes to the requirements of your API. + +## How to describe security schemes + +[securitySchemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object/security-schemes) are the actual details of the options provided in the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) sections of your document. The security schemes are components that are defined with the [components](https://spec.openapis.org/oas/v3.1.0#components-object) section of your document. Below is an example of the 5 types of security schemes described above and how they are defined: diff --git a/openapi/security/security-schemes/index.mdx b/openapi/security/security-schemes/index.mdx deleted file mode 100644 index 93c2741a..00000000 --- a/openapi/security/security-schemes/index.mdx +++ /dev/null @@ -1,117 +0,0 @@ ---- -asIndexPage: true -title: Standard Security Schemes ---- - -# Security Scheme Objects in OpenAPI - -Security scheme objects are defined in the [Components Object](../components.md) under the `securitySchemes` field. Each security scheme object has a unique key. [Security Requirement Objects](../security.md#security-requirement-object) elsewhere in the document reference security scheme objects by their keys. - -The following example requires a basic authentication scheme to access the `/drinks` endpoint: - -```yaml -paths: - /drinks: - get: - security: - - MyScheme17: [] -components: - securitySchemes: - MyScheme17: - type: http - scheme: basic -``` - -The `type` field is the overall category of authentication. The value of `type` determines the other fields the security object needs. - -To decide which authentication type to choose, see our article [OpenAPI Tips - How to Handle Auth](/post/openapi-tips-auth). - -## OpenAPI-Supported Authentication Types - -The following authentication types are supported in the OpenAPI Specification: - -- [API Key](/openapi/security/security-schemes/security-api-key) -- [Basic HTTP](/openapi/security/security-schemes/security-basic) -- [Bearer Token](/openapi/security/security-schemes/security-bearer) -- [OAuth 2.0](/openapi/security/security-schemes/security-oauth2) -- [OpenID Connect](/openapi/security/security-schemes/security-openid) -- Digest -- Mutual TLS - -## OpenAPI Example Security Scheme Schema - -Below is an example security schemes object with every possible field besides extensions. - -```yaml -components: - securitySchemes: - # apiKey ------------ - auth1: - description: Recommended authenticator - type: apiKey - in: query - name: key - - auth2: - type: apiKey - in: header - name: X-API-Key - - auth3: - type: apiKey - in: cookie - name: key - - # http ------------ - auth4: - type: http - scheme: basic - - auth5: - type: http - scheme: bearer - bearerFormat: JWT - - auth6: - type: http - scheme: digest # not supported by Speakeasy - - # mutualTLS ------------ - auth7: - type: mutualTLS # not supported by Speakeasy - - # openIdConnect ------------ - auth8: - type: openIdConnect - openIdConnectUrl: https://example.com/openidconfig.json - - # oauth2 ------------ - auth9: - type: oauth2 - flows: - authorizationCode: - scopes: - read: Grants read access - write: Grants write access - authorizationUrl: https://test.com/oauth/authorize - tokenUrl: https://test.com/oauth/token - refreshUrl: https://test.com/oauth/refresh - clientCredentials: - scopes: - read: Grants read access - write: Grants write access - tokenUrl: https://test.com/oauth/token - refreshUrl: https://test.com/oauth/refresh - implicit: - scopes: - read: Grants read access - write: Grants write access - authorizationUrl: https://test.com/oauth/authorize - refreshUrl: https://test.com/oauth/refresh - password: - scopes: - read: Grants read access - write: Grants write access - tokenUrl: https://test.com/oauth/token - refreshUrl: https://test.com/oauth/refresh -``` diff --git a/openapi/security/security-schemes/security-basic.mdx b/openapi/security/security-schemes/security-basic.mdx deleted file mode 100644 index ee972f30..00000000 --- a/openapi/security/security-schemes/security-basic.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Basic in OpenAPI best practices -description: "Implement Basic authentication using Security Schemes in your OpenAPI specification for better security, developer experience, and seamless integration." ---- -import { Table } from "@/mdx/components"; - -# Basic Security Scheme in OpenAPI - -A Basic security scheme is a simple authentication mechanism baked into the HTTP protocol that supports sending an Authorization header containing an encoded username and password. - -A Basic security scheme can be a relatively simple mechanism to get started with, but risks leaking easy-to-decode passwords if used incorrectly. - -Basic security also shares the downside of API keys in that the password is generally long-lived and if intercepted, can be used until it is either revoked or expires. - -The fields for a Basic security scheme are as follows: - - - -```yaml -components: - securitySchemes: - auth: - type: http - scheme: basic -security: - - auth: [] -``` diff --git a/openapi/security/security-schemes/security-bearer.mdx b/openapi/security/security-schemes/security-bearer.mdx deleted file mode 100644 index 2af3a296..00000000 --- a/openapi/security/security-schemes/security-bearer.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Bearer in OpenAPI best practices -description: "Implement Bearer authentication using Security Schemes in your OpenAPI specification for better security, developer experience, and seamless integration." ---- -import { Table } from "@/mdx/components"; - -# Bearer Security Scheme in OpenAPI - -The Bearer security scheme allows passing a token (most commonly a JWT) in the Authorization header. - -A Bearer security scheme is generally used for short-lived tokens granted to your API users through an additional login mechanism. Using a JWT allows for storing additional metadata within the token, which can be helpful for some use cases, such as storing scopes for permissions models. - -The fields for a Bearer security scheme are as follows: - -
- -```yaml -components: - securitySchemes: - auth: - type: http - scheme: bearer - bearerFormat: JWT -security: - - auth: [] -``` diff --git a/openapi/security/security-schemes/security-http.mdx b/openapi/security/security-schemes/security-http.mdx new file mode 100644 index 00000000..a1584abe --- /dev/null +++ b/openapi/security/security-schemes/security-http.mdx @@ -0,0 +1,150 @@ +--- +title: HTTP Basic in OpenAPI +description: "Implement Basic authentication using Security Schemes in your OpenAPI specification for better security, developer experience, and seamless integration." +--- + +import { Table } from "@/mdx/components"; + +# HTTP Security Scheme in OpenAPI + +The `http` security scheme is one of the most commonly used schemes because it covers anything using the HTTP header `Authorization`, which involves auth schemes like Basic, Digest, and Bearer. The full list of supports auth schemes for `type: http` is outsourced to the [IANA HTTP Authentication Scheme Registry](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml). + +Of that list, the most likely to be used for a modern API are: + +- [Bearer](#http-bearer) +- [Basic](#http-basic) +- [Digest](#http-digest) + +## HTTP Bearer + +The Bearer security scheme allows passing a token, which could be a JWT, API token, access token, or anything else. + +```http +GET /secrets + +Authorization: Bearer +``` + +The Bearer security scheme is generally used for short-lived tokens granted to your API users through an additional login mechanism. Using a JWT allows for storing additional metadata within the token, which can be helpful for some use cases, such as storing scopes for permissions models. + +The fields for a Bearer security scheme are as follows: + +
+ +So for example, a JWT token might look like this: + +```yaml +components: + securitySchemes: + auth: + type: http + scheme: bearer + bearerFormat: JWT +security: + - auth: [] +``` + +## HTTP Basic + +The Basic security scheme is a simple authentication mechanism baked into the HTTP protocol that supports sending an `Authorization` header containing a base64 encoded username and password. + +```http +GET /secrets + +Authorization: Basic dXNlcjpwYXNzd29yZA== +``` + +Basic is relatively simple mechanism to get started with, but risks leaking easy-to-decode passwords if used incorrectly. The example above is literally just `base64("user:password")`, but can fool some developers into thinking its actually encrypted or secret somehow. + +Much like API keys, another issue with Basic is that its generally working with long-lived credentials, and if intercepted these can be used by malicious actors until the credentials are revoked or expire. + +For these reasons it is generally best to avoid HTTP basic. + +Seeing as all APIs need to be accurately described warts and all, here's how to describe HTTP basic in OpenAPI: + +
+ +For example: + +```yaml +components: + securitySchemes: + auth: + type: http + scheme: basic +security: + - auth: [] +``` + +## HTTP Digest + +The Digest security scheme is a more secure alternative to Basic authentication. Instead of sending the username and password in plain text, Digest authentication uses a challenge-response mechanism that hashes credentials with a nonce provided by the server. This helps protect against replay attacks and credential interception. + +A typical Digest authentication request looks like this: + +```http +GET /secrets + +Authorization: Digest username="user", + realm="example", + nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", + uri="/secrets", + response="6629fae49393a05397450978507c4ef1", + opaque="5ccc069c403ebaf9f0171e9517f40e41" +``` + +The fields for a Digest security scheme in OpenAPI are as follows: + +
+ +For example: + +```yaml +components: + securitySchemes: + digestAuth: + type: http + scheme: digest +security: + - digestAuth: [] +``` diff --git a/openapi/security/security-schemes/security-mutualtls.mdx b/openapi/security/security-schemes/security-mutualtls.mdx new file mode 100644 index 00000000..f90ce605 --- /dev/null +++ b/openapi/security/security-schemes/security-mutualtls.mdx @@ -0,0 +1,49 @@ +--- +title: MutualTLS in OpenAPI +description: > + Mutual TLS (mTLS) is a security protocol that enhances the security of API + communication by requiring both the client and server to authenticate each + other using digital certificates. +--- +import { Table } from "@/mdx/components"; + +# Mutual TLS Security Scheme in OpenAPI + +Mutual TLS (mTLS) is a security protocol that enhances the security of API +communication by requiring both the client and server to authenticate each other +using digital certificates. This two-way authentication ensures that only +trusted parties can establish a connection, providing an additional layer of +security. + +OpenAPI lets you define a Mutual TLS security scheme using the `mutualTLS` type. + +## Defining a Mutual TLS Security Scheme + +To define a Mutual TLS security scheme in OpenAPI, you can use the following +structure: + +```yaml +components: + securitySchemes: + MutualTLS: + type: mutualTLS + description: Mutual TLS authentication for secure API communication. +``` + +There are no additional fields required for the `mutualTLS` type, it is purely +there to indicate that the API requires mutual TLS authentication. The +`description` field can be used to provide additional information about who to +talk to for a certificate, or what the process is for obtaining a certificate. + +```yaml +components: + securitySchemes: + MutualTLS: + type: mutualTLS + description: > + To access this API, you must provide a valid client certificate. + Please submit a request to the [infrastructure team](https://example.com) with + full information about what this application is to obtain a certificate. +``` + +That's all there is to this one. From 058a2f4fac413e1a80092b42b1893c7d287e0c81 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Sat, 31 May 2025 15:19:45 +0100 Subject: [PATCH 03/10] Apply suggestions from code review Co-authored-by: Chai Landau <112015853+chailandau@users.noreply.github.com> --- openapi/security/security-schemes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openapi/security/security-schemes.md b/openapi/security/security-schemes.md index 0d149965..3896fe55 100644 --- a/openapi/security/security-schemes.md +++ b/openapi/security/security-schemes.md @@ -24,7 +24,7 @@ components: Each security scheme has a unique name in the `securitySchemes` map, and the `type` field is particular standard or convention. -## Authentication Types +## Authentication types The following authentication types are supported by OpenAPI as of v3.1: @@ -111,7 +111,7 @@ components: refreshUrl: https://example.org/oauth/refresh ``` -To learn more about different types of security scheme, take a look at the guides for [API Key](/openapi/security/security-schemes/security-api-key), [HTTP Authorization](/openapi/security/security-schemes/security-basic) (Basic, Digest, Bearer, and more), [OAuth 2.0](/openapi/security/security-schemes/security-oauth2), [OpenID Connect](/openapi/security/security-schemes/security-openid), or [Mutual TLS](/openapi/security/security-schemes/security-mutualtls). +To learn more about different types of security schemes, take a look at the guides for [API Key](/openapi/security/security-schemes/security-api-key), [HTTP Authorization](/openapi/security/security-schemes/security-basic) (Basic, Digest, Bearer, and more), [OAuth 2.0](/openapi/security/security-schemes/security-oauth2), [OpenID Connect](/openapi/security/security-schemes/security-openid), or [Mutual TLS](/openapi/security/security-schemes/security-mutualtls). ## Global authentication vs endpoint authentication @@ -127,7 +127,7 @@ The important parts of the above example are the [security](https://spec.openapi ## How to describe security -The [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section is a list (actually a list of key-value pairs, but we will talk a bit more about that later) of security schemes that can be used to authenticate all operations or a particular operation (depending on the scope of the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) list). +The [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section is a list (of key-value pairs, but we will talk a bit more about that later) of security schemes that can be used to authenticate all operations or a particular operation (depending on the scope of the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) list). Below is an example of a number of different ways you can use the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section of your document: From d277e5cf94beda2ea87667265318e7eb7d3c249c Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Fri, 23 May 2025 19:01:41 +0100 Subject: [PATCH 04/10] fixed indenting in composition --- openapi/schemas/composition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi/schemas/composition.md b/openapi/schemas/composition.md index fce8f8a3..47659252 100644 --- a/openapi/schemas/composition.md +++ b/openapi/schemas/composition.md @@ -23,7 +23,7 @@ This can be done for a single value: ```yaml properties: - created_at: + created_at: oneOf: - type: string format: date-time From edfea031553a932e01445bf4aa89f67288a372ea Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Sat, 31 May 2025 15:20:41 +0100 Subject: [PATCH 05/10] feedback from review --- openapi/security/security-schemes.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openapi/security/security-schemes.md b/openapi/security/security-schemes.md index 3896fe55..4b0bd237 100644 --- a/openapi/security/security-schemes.md +++ b/openapi/security/security-schemes.md @@ -7,7 +7,7 @@ description: "Describe API authentication and authorization in OpenAPI using Sec Most APIs have some form of authorization and/or authentication, from simple API keys to scope-based OAuth 2 tokens on a tight rotation. APIs might support multiple methods in various combinations, so describing what goes where can become a bit of a challenge. OpenAPI helps by supporting a wide array of authorization and authentication methods, all of which can described under the larger umbrella of Security Schemes. -Security scheme objects are defined in the [Components Object](/openapi/components) in the `securitySchemes` section, and the `security` field in the root object or operation object references them. The `security` field is an array of security requirement objects, which are maps of security scheme names to scopes. +Security scheme objects are defined in the [Components Object](/openapi/components) in the `securitySchemes` section, and the `security` field references them. The `security` field is an array of security requirement objects, which are maps of security scheme names to scopes. ```yaml paths: @@ -22,11 +22,11 @@ components: scheme: basic ``` -Each security scheme has a unique name in the `securitySchemes` map, and the `type` field is particular standard or convention. +Each security scheme has a unique name in the `securitySchemes` map, and the `type` field specifies which authentication or authorization method will be used from a predefined list of supported types. -## Authentication types +## Security types -The following authentication types are supported by OpenAPI as of v3.1: +The following authorization/authentication types are supported by OpenAPI as of v3.1: - [API Key](/openapi/security/security-schemes/security-api-key) - [HTTP Authorization](/openapi/security/security-schemes/security-basic) (E.g: Basic, Digest, Bearer, and more) @@ -116,10 +116,10 @@ To learn more about different types of security schemes, take a look at the guid ## Global authentication vs endpoint authentication -Describing security in your OpenAPI document is then done through 1 of 2 different options: +Security can be applied at two levels in OpenAPI: -- **Global security:** the security you describe is available for all operations in your document. -- **Per operation security:** when described it overrides any global level security described. +- **Global security:** the security specified is available for all operations. +- **Per operation security:** only applied to the operation, overriding any global level security. Here is an example of describing security in the ways mentioned above: From 56ed626549cb3d04a06b9a786cfc5df7578abfef Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Sat, 31 May 2025 15:25:42 +0100 Subject: [PATCH 06/10] move old security requirement content out, belongs elsewhere --- openapi/security/security-schemes.md | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/openapi/security/security-schemes.md b/openapi/security/security-schemes.md index 4b0bd237..8715b594 100644 --- a/openapi/security/security-schemes.md +++ b/openapi/security/security-schemes.md @@ -3,7 +3,7 @@ title: "Security Schemes in OpenAPI" description: "Describe API authentication and authorization in OpenAPI using Security Schemes." --- -# Security Schemes in OpenAPI +# Security schemes in OpenAPI Most APIs have some form of authorization and/or authentication, from simple API keys to scope-based OAuth 2 tokens on a tight rotation. APIs might support multiple methods in various combinations, so describing what goes where can become a bit of a challenge. OpenAPI helps by supporting a wide array of authorization and authentication methods, all of which can described under the larger umbrella of Security Schemes. @@ -34,7 +34,7 @@ The following authorization/authentication types are supported by OpenAPI as of - [OpenID Connect](/openapi/security/security-schemes/security-openid) - [Mutual TLS](/openapi/security/security-schemes/security-mutualtls) -## OpenAPI Example Security Scheme Schema +## OpenAPI example security scheme schema Here's an example security schemes object with the sort of values likely to be used. The names are arbitrary and just used for clarity, but could be whatever you want. @@ -129,18 +129,9 @@ The important parts of the above example are the [security](https://spec.openapi The [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section is a list (of key-value pairs, but we will talk a bit more about that later) of security schemes that can be used to authenticate all operations or a particular operation (depending on the scope of the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) list). -Below is an example of a number of different ways you can use the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section of your document: - -The items in the list are key-value pairs with a name or key of a security scheme defined in the components section. We recommend giving them a boring name that explains what they are. - -The values are an array of scopes used only by the [oauth2](https://spec.openapis.org/oas/v3.1.0#oauth2-security-requirement) and [openIdConnect](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06) type schemes, and define what scopes are needed for the API. - -When used as shown above it provides a list of available schemes that can be used, with the end-user of the API being able to choose one of the available schemes to use to authenticate. - -If more than one scheme is required to authenticate an API, then that is where additional pairs in the key-value pairs come in. See the example below: - -Combining schemes like above give you the option to define AND/OR type functionality when it comes to the requirements of your API. - -## How to describe security schemes +``` +security: + - MySchemeAbc: [] +``` -[securitySchemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object/security-schemes) are the actual details of the options provided in the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) sections of your document. The security schemes are components that are defined with the [components](https://spec.openapis.org/oas/v3.1.0#components-object) section of your document. Below is an example of the 5 types of security schemes described above and how they are defined: +To learn more about how the `security` keyword works in the [OpenAPI Security guide](/openapi/security.mdx). From b4ea96d360087eaa293da995a306a25ee830e98c Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Sat, 31 May 2025 15:28:58 +0100 Subject: [PATCH 07/10] Apply suggestions from code review Co-authored-by: Chai Landau <112015853+chailandau@users.noreply.github.com> --- openapi/security/security-schemes/security-http.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openapi/security/security-schemes/security-http.mdx b/openapi/security/security-schemes/security-http.mdx index a1584abe..561f971b 100644 --- a/openapi/security/security-schemes/security-http.mdx +++ b/openapi/security/security-schemes/security-http.mdx @@ -68,13 +68,13 @@ GET /secrets Authorization: Basic dXNlcjpwYXNzd29yZA== ``` -Basic is relatively simple mechanism to get started with, but risks leaking easy-to-decode passwords if used incorrectly. The example above is literally just `base64("user:password")`, but can fool some developers into thinking its actually encrypted or secret somehow. +Basic is relatively simple mechanism to get started with, but risks leaking easy-to-decode passwords if used incorrectly. The example above is simply `base64("user:password")`, but can fool some developers into thinking its actually encrypted or secret. -Much like API keys, another issue with Basic is that its generally working with long-lived credentials, and if intercepted these can be used by malicious actors until the credentials are revoked or expire. +Much like API keys, another issue with Basic is that it's generally working with long-lived credentials, and if intercepted, these can be used by malicious actors until the credentials are revoked or expire. For these reasons it is generally best to avoid HTTP basic. -Seeing as all APIs need to be accurately described warts and all, here's how to describe HTTP basic in OpenAPI: +Since all APIs need to be accurately described (warts and all), here's how to describe HTTP basic in OpenAPI:
Date: Tue, 3 Jun 2025 16:26:21 +0100 Subject: [PATCH 08/10] more feedback --- openapi/security/security-schemes/security-http.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openapi/security/security-schemes/security-http.mdx b/openapi/security/security-schemes/security-http.mdx index 561f971b..def2b771 100644 --- a/openapi/security/security-schemes/security-http.mdx +++ b/openapi/security/security-schemes/security-http.mdx @@ -7,7 +7,7 @@ import { Table } from "@/mdx/components"; # HTTP Security Scheme in OpenAPI -The `http` security scheme is one of the most commonly used schemes because it covers anything using the HTTP header `Authorization`, which involves auth schemes like Basic, Digest, and Bearer. The full list of supports auth schemes for `type: http` is outsourced to the [IANA HTTP Authentication Scheme Registry](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml). +The `http` security scheme is one of the most commonly used schemes because it covers anything using the HTTP header `Authorization`. This is a big list, including auth schemes like HTTP Basic, HTTP Digest, and Bearer. The full list of supports auth schemes for `type: http` is outsourced to the [IANA HTTP Authentication Scheme Registry](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml). Of that list, the most likely to be used for a modern API are: @@ -72,9 +72,9 @@ Basic is relatively simple mechanism to get started with, but risks leaking easy Much like API keys, another issue with Basic is that it's generally working with long-lived credentials, and if intercepted, these can be used by malicious actors until the credentials are revoked or expire. -For these reasons it is generally best to avoid HTTP basic. +For these reasons it is generally best to avoid HTTP Basic. -Since all APIs need to be accurately described (warts and all), here's how to describe HTTP basic in OpenAPI: +Since all APIs need to be accurately described (warts and all), here's how to describe HTTP Basic in OpenAPI:
Date: Tue, 3 Jun 2025 16:57:14 +0100 Subject: [PATCH 09/10] improve security intro and smooth into requirements --- api-design/http-methods.md | 2 +- openapi/security.mdx | 123 +++++++++++++++++++++++---- openapi/security/security-schemes.md | 2 +- 3 files changed, 109 insertions(+), 18 deletions(-) diff --git a/api-design/http-methods.md b/api-design/http-methods.md index 5f618914..e2dfce1a 100644 --- a/api-design/http-methods.md +++ b/api-design/http-methods.md @@ -8,7 +8,7 @@ description: "Design intuitive, validated request bodies that make your API easy We learned about URLs in _[What is a URL?](/api-design/urls)_ which is how an API defines its "resources". If an API request were a sentence, the URL would be the noun. In this section, we'll cover the verbs of API requests: HTTP methods. -```curl focus:1[1:3] +```curl GET /places?lat=40.759211&lon=-73.984638 HTTP/1.1 Host: api.example.org ``` diff --git a/openapi/security.mdx b/openapi/security.mdx index 009d9cbc..3501dc7e 100644 --- a/openapi/security.mdx +++ b/openapi/security.mdx @@ -8,17 +8,16 @@ import { Table } from "@/mdx/components"; When designing an API, it is important to consider the security requirements for accessing the API. OpenAPI 3.1 provides a way to define security requirements at both the document and operation levels. -Security requirements are defined as a list of [Security Requirement Objects](/openapi/security#security-requirement-object) in the `security` section. Each object in the list represents a set of security requirements that must be satisfied to access the API. +Firstly, "security" is a general term which covers multiple authentication and authorization systems which are commonly used to keep API operations being used by only the intended actors. -To add security to an API as a whole, the `security` keyword must be defined at the [document](/openapi#openapi-document-structure) level. +In OpenAPI this is broken in two halves. -Likewise, to add security to a specific operation, the `security` keyword must be defined at the [operation](/openapi/paths/operations) level. +1. Security schemes +2. Security requirements -Security requirements defined at the operation level override the security requirements defined at the document level. +Security schemes are defined as reusable components. Security requirements invoke those schemes across the whole API, or on specific operations. -If not provided at the document level, the default security requirements are assumed to be `[]`, an empty array, meaning no security is required to access the API. - -The following example requires an API key to access the API: +Here's the basic structure of how security is defined in OpenAPI using a simple API key example: ```yaml security: @@ -27,10 +26,102 @@ components: securitySchemes: apiKey: type: apiKey - name: Authorization + name: Speakeasy-API-Key in: header ``` +## Supported security schemes in OpenAPI + +Before referencing a [security scheme](./security/security-schemes.md) as a requirement in the `security` section, it must be defined in the [Components Object](/openapi/components) under `securitySchemes`. + +OpenAPI v3.1 supports the following security schemes: + +- [API Key](/openapi/security/security-schemes/security-api-key) +- [HTTP Authorization](/openapi/security/security-schemes/security-basic) (E.g: Basic, Digest, Bearer, and more) +- [OAuth 2.0](/openapi/security/security-schemes/security-oauth2) +- [OpenID Connect](/openapi/security/security-schemes/security-openid) +- [Mutual TLS](/openapi/security/security-schemes/security-mutualtls) + +Once there are security schemes defined, they can be referenced in the `security` section of the OpenAPI document or at the operation level. + +## Security requirements + +Depending on the API, security requirements can be simple or complex. + +To make this more concrete, some examples are provided below. + +### Simple API Security + +All operations in an API may require an API key for access. This can be defined at the document level using the `security` section. + +```yaml focus[1:2] +security: + - apiKey: [] + +paths: + /drinks: + get: + operationId: listDrinks + summary: Get a list of drinks + post: + operationId: createDrink + summary: Create a new drink + +components: + securitySchemes: + apiKey: + type: apiKey + name: Speakeasy-API-Key + in: header +``` + +### Public Reads, Protected Writes + +A simple API might have some publicly accessible endpoints, but require an API key for others. The `security` section can be used to define the security requirements for the entire API or for specific operations. + +```yaml +# !focus(1:2) +security: [] # No global security requirements +paths: + /drinks: + get: + operationId: listDrinks + summary: Get a list of drinks + post: + operationId: createDrink + summary: Create a new drink + # !focus(1:2) + security: + - apiKey: [] # This operation requires an API key +``` + +### Multiple Security Schemes + +A more complex API might require different security requirements for different operations, or even allow multiple security schemes to be used interchangeably. + +```yaml +paths: + /drinks: + get: + operationId: listDrinks + summary: Get a list of drinks + security: + - + - apiKey: [] + - oauth2: # This operation can also be accessed with OAuth 2.0 + - read + post: + operationId: createDrink + summary: Create a new drink + security: + - apiKey: [] + - oauth2: # This operation can also be accessed with OAuth 2.0 + - write +``` + + +## + In valid OpenAPI v3.1, the [Security Requirement Objects](/openapi/security#security-requirement-object) listed in `security` sections may only reference [Security Scheme Objects](/openapi/security/security-schemes) that are defined in the [Components Object](/openapi/components) under the `securitySchemes` field. In other words, the `security` section may not contain inline security schemes, and it may not contain security schemes that are not defined yet. ## Security Requirement Object @@ -49,17 +140,17 @@ A Security Requirement Object defines a map of security scheme names to [scopes ]} /> -## Supported Security Schemes in OpenAPI +## Global authentication vs endpoint authentication -Before referencing a [Security Scheme](./security/security-schemes.md) as a requirement in the `security` section, it must be defined in the [Components Object](/openapi/components) under the `securitySchemes` field. +Security can be applied at two levels in OpenAPI: -OpenAPI v3.1 supports the following security schemes: +- **Global security:** the security specified is available for all operations. +- **Per operation security:** only applied to the operation, overriding any global level security. + +Here is an example of describing security in the ways mentioned above: + +The important parts of the above example are the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) and [securitySchemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object/security-schemes) sections. We will go into some details about how they are defined and the options available. -- [API Key](/openapi/security/security-schemes/security-api-key) -- [HTTP Authorization](/openapi/security/security-schemes/security-basic) (E.g: Basic, Digest, Bearer, and more) -- [OAuth 2.0](/openapi/security/security-schemes/security-oauth2) -- [OpenID Connect](/openapi/security/security-schemes/security-openid) -- [Mutual TLS](/openapi/security/security-schemes/security-mutualtls) ## Expressing Security Requirements in OpenAPI diff --git a/openapi/security/security-schemes.md b/openapi/security/security-schemes.md index 8715b594..7c3ecc06 100644 --- a/openapi/security/security-schemes.md +++ b/openapi/security/security-schemes.md @@ -134,4 +134,4 @@ security: - MySchemeAbc: [] ``` -To learn more about how the `security` keyword works in the [OpenAPI Security guide](/openapi/security.mdx). +Learn more about how the `security` keyword works in the [OpenAPI Security guide](/openapi/security.mdx). From f0151f796b567553c5e66c2bbda1abd3129ff6f2 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:31:47 +0100 Subject: [PATCH 10/10] finally tidied up security/requirements --- openapi/security.mdx | 178 ++++++++++++++------------- openapi/security/security-schemes.md | 23 +--- 2 files changed, 98 insertions(+), 103 deletions(-) diff --git a/openapi/security.mdx b/openapi/security.mdx index 3501dc7e..906355e3 100644 --- a/openapi/security.mdx +++ b/openapi/security.mdx @@ -44,11 +44,54 @@ OpenAPI v3.1 supports the following security schemes: Once there are security schemes defined, they can be referenced in the `security` section of the OpenAPI document or at the operation level. -## Security requirements +## Security Requirement Object + +A Security Requirement Object defines a map of security scheme names, with an array of [scopes or roles](#security-requirement-scopes-or-roles) that are required to access an API (or specific operation). + +The names **_must_** match the names of [Security Scheme Objects](/openapi/security/security-schemes) defined in the [Components Object](/openapi/components) under the `securitySchemes` field. + +
", required: "", description: "A list of [scopes or roles](#security-requirement-scopes-or-roles) required for the security scheme. If the security scheme type is `oauth2` or `openIdConnect`." } + ]} + columns={[ + { key: "field", header: "Field" }, + { key: "type", header: "Type" }, + { key: "required", header: "Required" }, + { key: "description", header: "Description" } + ]} +/> + + +## Global authentication vs endpoint authentication + +Security can be applied at two levels in OpenAPI: + +- **Global security:** the security specified is available for all operations. +- **Per operation security:** only applied to the operation, overriding any global level security. + +Here is an example of describing security in the ways mentioned above: + +```yaml +security: + - apiKey: [] # Global security requirement +paths: + /drinks: + get: + operationId: listDrinks + summary: Get a list of drinks + post: + operationId: createDrink + summary: Create a new drink + security: + - apiKey: [] # Per operation security requirement +``` -Depending on the API, security requirements can be simple or complex. +The important parts of the above example are the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) and [securitySchemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object/security-schemes) sections. -To make this more concrete, some examples are provided below. +## Working with security requirements + +Depending on the API, security requirements can be simple or complex. Some examples should hopefully help to illustrate how to work with security requirements in OpenAPI. ### Simple API Security @@ -87,10 +130,10 @@ paths: get: operationId: listDrinks summary: Get a list of drinks + # !focus(1:5) post: operationId: createDrink summary: Create a new drink - # !focus(1:2) security: - apiKey: [] # This operation requires an API key ``` @@ -99,70 +142,73 @@ paths: A more complex API might require different security requirements for different operations, or even allow multiple security schemes to be used interchangeably. +Here is an example where the API can be accessed with either an API key or OAuth 2.0. OAuth 2 allows for more granular access control using the concept of scopes, which can be defined in the `securitySchemes` section and referred to in the `security` section for specific operations. + ```yaml +# focus(3:16) paths: /drinks: get: operationId: listDrinks summary: Get a list of drinks security: - - - - apiKey: [] - - oauth2: # This operation can also be accessed with OAuth 2.0 + - apiKey: [] # Can be access with an API key, or... + - oauth2: # an oauth2 token which has the read scope - read post: operationId: createDrink summary: Create a new drink security: - - apiKey: [] - - oauth2: # This operation can also be accessed with OAuth 2.0 + - apiKey: [] # Can be accessed with an API key, or... + - oauth2: # an oauth2 token which has the write scope - write -``` - - -## - -In valid OpenAPI v3.1, the [Security Requirement Objects](/openapi/security#security-requirement-object) listed in `security` sections may only reference [Security Scheme Objects](/openapi/security/security-schemes) that are defined in the [Components Object](/openapi/components) under the `securitySchemes` field. In other words, the `security` section may not contain inline security schemes, and it may not contain security schemes that are not defined yet. - -## Security Requirement Object - -A Security Requirement Object defines a map of security scheme names to [scopes or roles](#security-requirement-scopes-or-roles) that are required to access the API. The names **_must_** match the names of [Security Scheme Objects](/openapi/security/security-schemes) defined in the [Components Object](/openapi/components) under the `securitySchemes` field. - -
", required: "", description: "A list of [scopes or roles](#security-requirement-scopes-or-roles) required for the security scheme. If the security scheme type is `oauth2` or `openIdConnect`." } - ]} - columns={[ - { key: "field", header: "Field" }, - { key: "type", header: "Type" }, - { key: "required", header: "Required" }, - { key: "description", header: "Description" } - ]} -/> - -## Global authentication vs endpoint authentication - -Security can be applied at two levels in OpenAPI: - -- **Global security:** the security specified is available for all operations. -- **Per operation security:** only applied to the operation, overriding any global level security. -Here is an example of describing security in the ways mentioned above: +components: + securitySchemes: + apiKey: + type: apiKey + name: Speakeasy-API-Key + in: header + oauth2: + type: oauth2 + flows: + authorizationCode: + authorizationUrl: https://example.com/oauth/authorize + tokenUrl: https://example.com/oauth/token + scopes: + read: Read access to the API + write: Write access to the API +``` -The important parts of the above example are the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) and [securitySchemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object/security-schemes) sections. We will go into some details about how they are defined and the options available. +## Security requirement scopes or roles in openapi +When defining an OAuth 2.0 or OpenID Connect [Security Requirement Object](/openapi/security#security-requirement-object) for an operation, the `{securitySchemeName}` field should contain a list of scopes or roles required for the security scheme. -## Expressing Security Requirements in OpenAPI +For example, the following security requirement object requires the `read` and `write` scopes for the `oauth2` security scheme: -The `security` keyword can be used in the following ways to express security requirements. +```yaml +paths: + /drinks: + get: + operationId: listDrinks + summary: Get a list of drinks + # Operation requires read and write scopes + security: + - oauth2: + - read + - write + # ... +``` -### Disabling Security in OpenAPI +### Disabling security requirements -Security can be _disabled_ for a specific operation by providing an empty array (`[]`) in the list of security requirements. +Security can be disabled for a specific operation by providing an empty array (`[]`) in the list of security requirements. -In this example, the `POST` operation in the `/auth` path does not require security: +In this example, the `POST` operation in the `/auth` path does not require security, despite the global security requirement of an API key: ```yaml +security: + - apiKey: [] paths: /auth: post: @@ -172,7 +218,7 @@ paths: # ... ``` -### Optional Security +### Optional security Security can also be made optional by providing an empty object (`{}`) in the list of security requirements. @@ -184,7 +230,7 @@ security: - {} ``` -### Adding Optional Security to a Specific Operation +### Adding optional security to a specific operation Security can be made _optional_ for a specific operation by providing an empty object (`{}`) in the list of security requirements. @@ -203,21 +249,7 @@ paths: # ... ``` -### Allowing a Choice of Security Schemes - -To allow users to choose between multiple different security requirements, define the `security` keyword as a list of [Security Requirement Objects](/openapi/security#security-requirement-object). The API consumer can choose one of the requirements to authenticate. - -In this example, the API may be accessed with an API key **OR** OAuth 2.0: - -```yaml -security: # apiKey OR oauth2 can be used - - apiKey: [] - - oauth2: - - read - - write -``` - -### Requiring Multiple Security Schemes Together +### Requiring multiple security schemes together If multiple schemes are required together, then the [Security Requirement Object](/openapi/security#security-requirement-object) should be defined with multiple security schemes. @@ -229,7 +261,7 @@ security: # both apiKey AND basic is required basic: [] ``` -### Complex Authorization Scenarios +### Complex authorization scenarios This **AND**/**OR** logic along with optional (`{}`) security can be used in any combination to express complex authorization scenarios. @@ -243,23 +275,3 @@ security: # apiKey AND oauth2 OR basic - write - basic: [] ``` - -## Security Requirement Scopes or Roles in OpenAPI - -When defining an OAuth 2.0 or OpenID Connect [Security Requirement Object](/openapi/security#security-requirement-object) for an operation, the `{securitySchemeName}` field should contain a list of scopes or roles required for the security scheme. - -For example, the following security requirement object requires the `read` and `write` scopes for the `oauth2` security scheme: - -```yaml -paths: - /drinks: - get: - operationId: listDrinks - summary: Get a list of drinks - # Operation requires read and write scopes - security: - - oauth2: - - read - - write - # ... -``` diff --git a/openapi/security/security-schemes.md b/openapi/security/security-schemes.md index 7c3ecc06..6b393a82 100644 --- a/openapi/security/security-schemes.md +++ b/openapi/security/security-schemes.md @@ -113,25 +113,8 @@ components: To learn more about different types of security schemes, take a look at the guides for [API Key](/openapi/security/security-schemes/security-api-key), [HTTP Authorization](/openapi/security/security-schemes/security-basic) (Basic, Digest, Bearer, and more), [OAuth 2.0](/openapi/security/security-schemes/security-oauth2), [OpenID Connect](/openapi/security/security-schemes/security-openid), or [Mutual TLS](/openapi/security/security-schemes/security-mutualtls). +## Security requirements -## Global authentication vs endpoint authentication +Once these security schemes are defined, they can be referenced by the `security` keyword. -Security can be applied at two levels in OpenAPI: - -- **Global security:** the security specified is available for all operations. -- **Per operation security:** only applied to the operation, overriding any global level security. - -Here is an example of describing security in the ways mentioned above: - -The important parts of the above example are the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) and [securitySchemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object/security-schemes) sections. We will go into some details about how they are defined and the options available. - -## How to describe security - -The [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) section is a list (of key-value pairs, but we will talk a bit more about that later) of security schemes that can be used to authenticate all operations or a particular operation (depending on the scope of the [security](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) list). - -``` -security: - - MySchemeAbc: [] -``` - -Learn more about how the `security` keyword works in the [OpenAPI Security guide](/openapi/security.mdx). +**Learn more about security requirements in the [Security Requirements](/openapi/security) section.**