# The OAuth 2 security scheme in OpenAPI
Source: https://speakeasy.com/openapi/security/security-schemes/security-oauth2

import { Table } from "@/mdx/components";



OAuth 2 is a popular open authentication mechanism that supports an authentication flow allowing servers to authenticate on behalf of a user or an entire application.

While more generally used for authenticating end users (for example, logging the user in with Facebook), OAuth 2 is also used for machine-to-machine flows where a whole application authenticates itself with the API (for example, connecting Shopify to Xero).

OAuth 2 is considered more secure than other mechanisms due to its granting privileges through short-lived tokens that limit damage from intercepted tokens. Tokens that can only be used for a day can only cause damage for a day. A well-built API won't allow short-lived tokens to be used to escalate privileges (for example, to change a user's password), so less damage can be done while the token is valid.

The OAuth 2 protocol defines multiple ways of building a request against the `tokenUrl` endpoint and supports multiple flows at once, so that developers can set up different types of integration for the same API.

## Defining the OAuth 2 security scheme

The fields for an OAuth 2 security scheme are as follows:

<Table
  data={[
    { field: "`type`", type: "String", required: "✅", description: "`oauth2`" },
    { field: "`description`", type: "String", required: "", description: "Human-readable information. This may contain [CommonMark syntax](https://spec.commonmark.org/) to provide a rich description." },
    { field: "`flows`", type: "Map[{key}, [OAuth Flow Object](#oauth-flow-object)]", required: "✅", description: "An object containing configuration for the available OAuth 2 flows. Valid keys are `implicit`, `password`, `clientCredentials`, and `authorizationCode`." },
    { field: "`x-*`", type: "[Extensions](/openapi/extensions)", required: "", description: "Any number of extension fields can be added to the Security Scheme Object to be used by tooling and vendors." }
  ]}
  columns={[
    { key: "field", header: "Field" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

The following example shows an OAuth 2 security scheme using the `clientCredentials` flow:

```yaml
components:
  securitySchemes:
    clientCredentials:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
security:
  - clientCredentials: []
```

## Defining OAuth flows

The value of the [OAuth Flows Object](https://spec.openapis.org/oas/v3.1.0#oauth-flows-object) is a map of [OAuth Flow Objects](https://spec.openapis.org/oas/v3.1.0#oauth-flow-object).

The OpenAPI Specification 3.1 supports the following four OAuth Flow Objects:

- The [Client Credentials](#the-client-credentials-flow) flow (using `clientCredentials`, previously `application` in OpenAPI 2.0)
- The [Authorization Code](#the-authorization-code-flow) flow (using `authorizationCode`, previously `accessCode` in OpenAPI 2.0)
- The [Password](#the-password-flow) flow (using `password`)
- The [Implicit](#the-implicit-flow) flow (using `implicit`)

Each OAuth Flow Object has its own configuration parameters, so let's look at them individually.

### The Client Credentials flow

The Client Credentials flow is generally used for machine-to-machine communication that doesn't require a specific user's permission and context. Think of an entire application integrating with a whole other application, to sync billing information or other organization-wide information.

<Table
  data={[
    { field: "`tokenUrl`", type: "String", required: "✅", description: "The token URL to be used for this flow." },
    { field: "`refreshUrl`", type: "String", required: "", description: "The URL to be used for refreshing the token. No refresh URL means the token is not refreshable." },
    { field: "`scopes`", type: "Map[String, String]", required: "✅", description: "The available scopes for the OAuth 2 flow, with a description for each scope. Although the specification requires this field, it can be an empty object." },
    { field: "`x-*`", type: "[Extensions](/openapi/extensions)", required: "", description: "Any number of extension fields can be added to an OAuth Flow Object to be used by tooling and vendors to add additional metadata and functionality to the OpenAPI Specification." }
  ]}
  columns={[
    { key: "field", header: "Field" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

The example below shows an OAuth 2 security scheme using the `clientCredentials` flow:

```yaml
components:
  securitySchemes:
    clientCredentials:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access
```

### The Authorization Code flow

The Authorization Code flow is generally used for server-side applications that can safely store the client secret.

<Table
  data={[
    { field: "`authorizationUrl`", type: "String", required: "✅", description: "The authorization URL to be used for this flow." },
    { field: "`tokenUrl`", type: "String", required: "✅", description: "The token URL to be used for this flow." },
    { field: "`refreshUrl`", type: "String", required: "", description: "The URL to be used for refreshing the token. No refresh URL means the token is not refreshable." },
    { field: "`scopes`", type: "Map[String, String]", required: "✅", description: "The available scopes for the OAuth 2 flow, with a description for each scope. Although the specification requires this field, it can be an empty object." },
    { field: "`x-*`", type: "[Extensions](/openapi/extensions)", required: "", description: "Any number of extension fields can be added to an OAuth Flow Object to be used by tooling and vendors to add additional metadata and functionality to the OpenAPI Specification." }
  ]}
  columns={[
    { key: "field", header: "Field" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

The following example shows an OAuth 2 security scheme using the `authorizationCode` flow:

```yaml
components:
  securitySchemes:
    authorizationCode:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://speakeasy.bar/oauth2/authorize
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access
```

### The Password flow

The Password flow is generally used for trusted first-party clients that can securely store the client secret.

<Table
  data={[
    { field: "`tokenUrl`", type: "String", required: "✅", description: "The token URL to be used for this flow." },
    { field: "`refreshUrl`", type: "String", required: "", description: "The URL to be used for refreshing the token. No refresh URL means the token is not refreshable." },
    { field: "`scopes`", type: "Map[String, String]", required: "✅", description: "The available scopes for the OAuth 2 flow, with a description for each scope. Although the specification requires this field, it can be an empty object." },
    { field: "`x-*`", type: "[Extensions](/openapi/extensions)", required: "", description: "Any number of extension fields can be added to an OAuth Flow Object to be used by tooling and vendors to add additional metadata and functionality to the OpenAPI Specification." }
  ]}
  columns={[
    { key: "field", header: "Field" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

The following example shows an OAuth 2 security scheme using the `password` flow:

```yaml
components:
  securitySchemes:
    password:
      type: oauth2
      flows:
        password:
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access
```

### The Implicit flow 

The Implicit flow is generally used for browser or client-side applications that can't keep a client secret because, in a browser, all code and data are available to the user. Although it was popular for a while, the IETF's OAuth working group [recommends **not using the implicit grant** anymore](https://medium.com/oauth-2/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926).

<Table
  data={[
    { field: "`authorizationUrl`", type: "String", required: "✅", description: "The authorization URL to be used for this flow." },
    { field: "`refreshUrl`", type: "String", required: "", description: "The URL to be used for refreshing the token. No refresh URL means the token is not refreshable." },
    { field: "`scopes`", type: "Map[String, String]", required: "✅", description: "The available scopes for the OAuth 2 flow, with a description for each scope. Although the specification requires this field, it can be an empty object." },
    { field: "`x-*`", type: "[Extensions](/openapi/extensions)", required: "", description: "Any number of extension fields can be added to an OAuth Flow Object to be used by tooling and vendors to add additional metadata and functionality to the OpenAPI Specification." }
  ]}
  columns={[
    { key: "field", header: "Field" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

The following example shows an OAuth 2 security scheme using the `implicit` flow:

```yaml
components:
  securitySchemes:
    implicit:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://speakeasy.bar/oauth2/authorize
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access
```

## Using OAuth 2 with multiple flows

If needed, you can use multiple OAuth 2 flows in a single API by describing each of the flows in the OAuth Flows Object.

Consider the following example, which uses both the `authorizationCode` flow and the `clientCredentials` flow:

```yaml
components:
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://speakeasy.bar/oauth2/authorize
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access
        clientCredentials:
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access
security:
  - oauth2: []
```

If you have an API in which different endpoints support different flows, split the endpoints into different `securitySchemes`.

Consider this example, where the whole API is secured by `clientCredentials` except for the `/profile` endpoint, which requires `authorizationCode`:

```yaml
security:
  - MachineAuth: []

paths:
  "/profile": 
    security: 
      - UserAuth: []

components:
  securitySchemes:
    UserAuth:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://speakeasy.bar/oauth2/authorize
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access

    MachineAuth:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            read: Grants read access
            write: Grants write access

```

## Scopes in OAuth 2

In an API, scopes define more granular permissions or access controls. APIs can use very generic scopes, like `read` and `write`.

Other APIs focus on different resources:

- `invoices`
- `customers`
- `orders`

Some go even further and break scopes into resources and actions:

- `invoices:read`
- `invoices:write`
- `invoices:delete`
- `customers:read`
- `customers:write`
- `customers:delete`
- `orders:read`
- `orders:write`
- `orders:delete`

You can use detailed scopes not only to ensure that users don't see anything they shouldn't, but to limit accidental data loss when misconfigured applications go rogue.

Scopes are defined in the `scopes` field of the OAuth Flow Object, and the
scopes required for a specific operation are defined in the Security Requirement Object (the `security` field) for
that operation:

```yaml
components:
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://speakeasy.bar/oauth2/authorize
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes:
            'drinks:read': Grants read access to drinks resource
            'drinks:write': Grants write access to drinks resource
paths:
  /drinks:
    get:
      operationId: listDrinks
      summary: Get a list of drinks
      security:
        - oauth2:
            - drinks:read
```

### Using OAuth 2 without scopes

Scopes are optional, and an API may not use them at all. To create an API without scopes, define `scopes` as an empty object `{}` and define the security requirement (for example, `oauth2` below) as an empty list of scopes `[]`.

```yaml
components:
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://speakeasy.bar/oauth2/authorize
          tokenUrl: https://speakeasy.bar/oauth2/token
          refreshUrl: https://speakeasy.bar/oauth2/refresh
          scopes: {}
security:
  - oauth2: []
```

## OAuth 2.1 and Device Authorization

OAuth 2.1 is a simplified version of OAuth 2 that combines its best practices and removes the less secure flows. There aren't many changes directly related to OpenAPI, so the existing structure works fine for both versions.

For more information on the changes and improvements made in OAuth 2.1, refer to [the OAuth 2.1 specification](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13).

**Device Authorization** is a new OAuth flow (also called a grant) that is not yet supported in the OpenAPI Specification 3.1. It will be added in the OpenAPI Specification 3.2, which is currently in development.

For more information on the Device Authorization grant, take a look at the specification for the [OAuth 2.0 Device Authorization grant](https://datatracker.ietf.org/doc/html/rfc8628).