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/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 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. diff --git a/openapi/security.mdx b/openapi/security.mdx index 1b77e5bc..906355e3 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,15 +26,29 @@ components: securitySchemes: apiKey: type: apiKey - name: Authorization + name: Speakeasy-API-Key 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. +## 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 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. +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. -## 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 the `securitySchemes` field. +## 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 +``` + +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. + +## 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 + +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 + # !focus(1:5) + post: + operationId: createDrink + summary: Create a new drink + 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. + +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: [] # 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: [] # Can be accessed with an API key, or... + - oauth2: # an oauth2 token which has the write scope + - write + +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 +``` -OpenAPI 3.1 supports the following security schemes: +## Security requirement scopes or roles in openapi -- [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 +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: @@ -83,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. @@ -95,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. @@ -114,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. @@ -140,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. @@ -154,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 b1e18563..6b393a82 100644 --- a/openapi/security/security-schemes.md +++ b/openapi/security/security-schemes.md @@ -1,117 +1,120 @@ --- -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 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 specifies which authentication or authorization method will be used from a predefined list of supported types. -To decide which authentication type to choose, see our article [OpenAPI Tips - How to Handle Auth](/post/openapi-tips-auth). +## Security types -## OpenAPI-Supported Authentication Types - -The following authentication types are supported in the OpenAPI Specification: +The following authorization/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 +## 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 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 + +Once these security schemes are defined, they can be referenced by the `security` keyword. + +**Learn more about security requirements in the [Security Requirements](/openapi/security) section.** 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..def2b771 --- /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`. 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: + +- [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 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 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. + +Since 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.