# The HTTP security scheme in OpenAPI
Source: https://speakeasy.com/openapi/security/security-schemes/security-http

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



The `http` security scheme is one of the most commonly used schemes because it covers anything using the HTTP header `Authorization`. This is a long list, including auth schemes like HTTP Basic, HTTP Digest, and HTTP Bearer. The full list of supported 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 auth schemes most likely to be used for a modern API are:

- [Bearer](#http-bearer)
- [Basic](#http-basic)
- [Digest](#http-digest)

## HTTP Bearer

The Bearer auth scheme allows you to pass a token, which could be a JSON Web Token (JWT), API token, access token, or other token-based form of authentication.

```http
GET /secrets

Authorization: Bearer <token>
```

Bearer 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 auth scheme are as follows:

<Table
  data={[
    { field: "`type`", type: "String", required: "✅", description: "`http`" },
    {
      field: "`description`",
      type: "String",
      required: "",
      description:
        "Human-readable information. This may contain [CommonMark syntax](https://spec.commonmark.org/) to provide a rich description.",
    },
    {
      field: "`scheme`",
      type: "String",
      required: "✅",
      description: "`bearer`",
    },
    {
      field: "`bearerFormat`",
      type: "String",
      required: "",
      description:
        "A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation purposes.",
    },
    {
      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" },
  ]}
/>

So, for example, a JWT might look like this:

```yaml
components:
  securitySchemes:
    auth:
      type: http
      scheme: bearer
      bearerFormat: JWT
security:
  - auth: []
```

## HTTP Basic

The Basic auth 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 a relatively simple mechanism for getting started, but it risks leaking easy-to-decode passwords if used incorrectly. The example above is simply a `base64("user:password")` but it can fool some developers into thinking the password is actually encrypted or secret.

Much like API keys, another issue with Basic is that it generally works with long-lived credentials, and if intercepted, these can be used by malicious actors until the credentials expire or are revoked.

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 a Basic auth scheme in OpenAPI:

<Table
  data={[
    { field: "`type`", type: "String", required: "✅", description: "`http`" },
    {
      field: "`description`",
      type: "String",
      required: "",
      description:
        "Human-readable information. This may contain [CommonMark syntax](https://spec.commonmark.org/) to provide a rich description.",
    },
    {
      field: "`scheme`",
      type: "String",
      required: "✅",
      description: "`basic`",
    },
    {
      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" }
  ]}
/>

For example: 

```yaml
components:
  securitySchemes:
    auth:
      type: http
      scheme: basic
security:
  - auth: []
```

The description field can be used to warn developers about the risks of using Basic authentication, and to encourage them to use more secure alternatives like Bearer tokens or OAuth 2.0.

```yaml
components:
  securitySchemes:
    auth:
      type: http
      scheme: basic
      description: |
        **Warning:** Basic authentication sends credentials in an easily decodable format, so this
        should only be used over HTTPS. Instead of using your password please only use a short lived access token
        which can be obtained from <https://example.com/tokens>.
```

## HTTP Digest

The Digest auth scheme is a more secure alternative to Basic authentication. Instead of sending the username and password in plain text, Digest 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 auth scheme in OpenAPI are as follows:

<Table
  data={[
    { field: "`type`", type: "String", required: "✅", description: "`http`" },
    {
      field: "`description`",
      type: "String",
      required: "",
      description:
        "Human-readable information. This may contain [CommonMark syntax](https://spec.commonmark.org/) to provide a rich description.",
    },
    {
      field: "`scheme`",
      type: "String",
      required: "✅",
      description: "`digest`",
    },
    {
      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" },
  ]}
/>

For example:

```yaml
components:
  securitySchemes:
    digestAuth:
      type: http
      scheme: digest
security:
  - digestAuth: []
```

## Overlap with other security schemes

The HTTP security scheme overlaps with a few other, more specific schemes.

The [API Key](/openapi/security/security-schemes/security-api-key) security scheme is better suited to non-standard API keys using custom headers, like `Acme-API-Key`, whereas the HTTP security scheme is specifically designed for HTTP-based authentication methods using the `Authorization` header.

The HTTP security scheme also has some overlap with the [OAuth 2.0](/openapi/security/security-schemes/security-oauth2) and [OpenID Connect](/openapi/security/security-schemes/security-openid) security schemes. These may use bearer tokens and the JWT format, but they are more complex and involve additional flows and endpoints. It's better to use the `oauth2` or `openidConnect` security scheme for an API using the OAuth 2.0 or OpenID Connect protocol than to try to cover it with the `http` security scheme.

### Unauthorized response

As well as describing the security requirements, it also helps to describe what happens when those requirements are not met.

The `401 Unauthorized` response can be returned for requests with missing security credentials, showing what the client can expect to see if this happens. This response includes the `WWW-Authenticate` header, which you may want to mention. As with other generic responses, the `401` response can be defined as a component in the `responses` section, and referenced with `$ref` to avoid repetition.

```yaml
paths:
  /drinks:
    get:
      # ...
      responses:
        # ...
        '401':
          $ref: '#/components/responses/HttpErrorUnauthorized'
    post:
      # ...
      responses:
        # ...
        '401':
          $ref: '#/components/responses/HttpErrorUnauthorized'

components:
  responses:
    HttpErrorUnauthorized:
      description: Unauthorized
      headers:
        WWW_Authenticate:
          schema:
            type: string
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'
```

Learn more about describing [responses](/openapi/responses).

## Forbidden response

The `403 Forbidden` response can be returned for requests that are authenticated but not authorized to access the resource. This response can also include the `WWW-Authenticate` header, but it is not required.

As with the `401` response, the `403` response can be defined as a component in the `responses` section, and referenced with `$ref` to avoid repetition. This error uses the HTTP Problem Details format, which is a standard means of providing more information about the error.

```yaml
paths:
  /drinks:
    get:
      # ...
      responses:
        # ...
        '403':
          $ref: '#/components/responses/HttpErrorForbidden'
    post:
      # ...
      responses:
        # ...
        '403':
          $ref: '#/components/responses/HttpErrorForbidden'
components:
  responses:
    HttpErrorForbidden:
      description: Forbidden
      headers:
        WWW_Authenticate:
          type: string
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'
```