API Authentication Methods for OAS Security🛡️

What keeps you up at night as an API developer or professional? According to Postman’s State of API Report 2023, over 40,000 developers and API professionals identified “improper authentication, authorization, or access control” as the top API security risk for their organization. Obviously, picking the appropriate API authentication method is critical. But how do you decide which one? 🤔

At the time of writing, OpenAPI Specification (OAS) 3.1.0 supports the following security schemes:

  • API Key 🔑
  • HTTP Authentication 🌐
  • OAuth 2.0 🔐
  • OpenID Connect 👤
  • Mutual TLS 🤝

Ready to dive into API authentication methods? We’ll walk you through each method, covering everything from security and complexity considerations to suitable scenarios. You’ll be equipped with the knowledge to choose the right one for your situation. And if you need to change your API authentication method, we’ve got some tips to ensure a smooth transition for your API users.

Authentication 🪪 vs. authorization 🚪

Before diving into the API authentication methods, let’s make sure we understand the following high-level concepts. Let’s imagine you are logging into your online bank account:

  • Identity: Who you claim to be. This can be a user, organization, or application.

For your bank account, you might claim to be John Doe by entering your username (john.doe).

  • Authentication: When you prove your identity. 

Here you enter your password. The system then checks the password against its records to verify that you are indeed John Doe.

  • Authorization: When you prove a right to access. You verify that you have the proper permission to request specific resources. 

Once authenticated, the system checks what John Doe is allowed to see and do. For example, viewing your own account details and paying your bills. The system makes sure you only see and do what your account allows, so no sneaky business.

API authentication methods breakdown

Generally speaking, the more secure the API authentication method, the more complex it gets.

SCHEMESECURITY (1-5)COMPLEXITY (1-5)
API key authentication21
Basic authentication11
Bearer authentication32
OAuth 2.043
OpenID Connect4.54
Mutual TLS55

A summarization table (complexity and security) of the API authentication schemes. Source: Author

API key 🔑

API key authentication involves the API provider giving clients (users or applications) unique API keys. Think of these keys as static identifiers. For example, a mock API key might look like `pk_live_abcdefghijklmnopqrstuvwxyz0123`. When sending a request, the client includes its API key in the Authorization header or a custom header `X-API-Key`. As a safety tip, don’t put API keys in the query string or request body.

“`

Authorization: Apikey client_apikey

“`

Using API keys is simple. But remember, they aren’t encrypted and don’t typically expire. If an API key is compromised, the attacker can use it until revocation. ⚠️

API keys may be used for coarse-grained authorization by creating multiple API keys configured with different levels of access. For example, one API key has read-only access for a reporting application, while another API key has read-and-write access for an internal application. Keep in mind this increases the complexity. Not only are there more keys to manage (a client may have several API keys), but more logic to check the access level.

This method works well for less sensitive environments, such as a read-only or internal API. For instance, a public API for fetching weather forecasts or a private API used for a company’s internal web tool.

HTTP authentication 🌐

Let’s cover the two HTTP authentication schemes, which should be used over secured connections via HTTPS.

Basic authentication

With basic authentication, the client includes its username and password in the Authorization header when making a request. The `username:password` combination is Base64 encoded.

“`

Authorization: Basic Base64(username:password)

“`

This method is easy to implement in the request header, without needing a login page. However, basic authentication is pretty vulnerable to compromise as your username and password aren’t encrypted. This method can also be a target for brute-force password attacks, so it isn’t recommended for production environments. ⚠️

Bearer authentication

Bearer authentication, also known as token-based authentication, involves the server generating tokens for clients (usually after logins). The client then includes this token, an opaque string, in the Authorization header when making a request

“`

Authorization: Bearer client_token

“`

Bearer tokens are a general token type that gives access to whomever holding the token. The API provider decides the specific token format, such as JSON Web Token (JWT). JWTs look like `header.payload.signature`:

  • Header: Specifies the token type and hashing algorithm used for signing the token (e.g. HMAC with SHA-256).
  • Payload: Contains the claims about the client, such as user data or metadata.
  • Signature: This is made up of `Base64URL(header).Base64URL(payload)` and signed by the server with a secret key using the specified algorithm. 

Bearer tokens can be encrypted and usually have an expiration date, making them more secure than API keys and basic authentication. However, if a token is compromised, the attacker can use it until revocation or expiration. ⚠️

There’s a little bit of complexity with cryptography, but stateless authentication is quite efficient and can be done in under 1 millisecond. Plus, tokens are small and portable, making them easy to share and scale.

This method is great for situations where you don’t want to send login credentials with each request. For instance, mobile apps or single-page applications calling your API can use the stored token after initial login.

OAuth 2.0 🔐

OAuth 2.0 is an authorization protocol that lets clients access resources without revealing user login credentials. It handles authentication as part of its flow.

     +——–+                                                           +—————+

     |              |–(A)- Authorization Request ->|   Resource     |

     |              |                                                          |     Owner        |

     |              |<-(B)– Authorization Grant —  |                          |

    |              |                                                           +—————+

                                |              |

   |              |                                                          +—————+

     |              |–(C)– Authorization Grant –>| Authorization |

     | Client  |                                                        |     Server           |

     |              |<-(D)—– Access Token ——-  |                            |

   |              |                                                          +—————+

                                |              |

  |              |                                                          +—————+

    |              |–(E)—– Access Token ——->|     Resource     |

   |              |                                                       |     Server           |

   |              |<-(F)— Protected Resource –|                            |

    +——–+                                                          +—————+

Diagram of abstract OAuth 2.0 protocol flow. Source: https://www.rfc-editor.org/rfc/rfc6749

OAuth 2.0 implementations use the following tokens to work their magic:

  • Access token: Grants access to resources with specified scope and optional expiration. Supports Bearer and Message Authentication Code (MAC) token types.
  • Refresh token (optional): Retrieves a new access token if the current one has expired. 

The protocol defines four major roles:

  • Resource owner (user): Grants access to their protected resources.
  • Client (application): Handles the authorization flow and accesses the protected resources on behalf of the resource owner.
  • Authorization server: Authenticates and issues the access token (and optional refresh token) based on the resource owner’s permissions.
  • Resource server: Returns the requested resources based on the access token.

The protocol supports several grant types or flows to suit different needs:

  • Authorization code (most common): The authorization server gives a single-use code to the client, which is then exchanged for an access token.
  • Implicit: The client gets the access token immediately after the resource owner grants consent. This is common for client-side applications and devices where storing user credentials securely is difficult.
  • Resource owner password credentials: The resource owners share their login credentials directly with the client. Only use this with trusted clients, like an official application from the API provider. ⚠️
  • Client credentials: The client’s own credentials are used to access their protected resources. This is common for server-to-server authentication.

Based on the bearer authentication scheme, the client simply includes the access token in the Authorization header when making API requests.

OAuth 2.0 can work in either stateless or stateful mode. Stateless mode sends session state with each request and is faster. Stateful mode stores session state on the server and is more secure. Use stateless mode for public APIs with enormous requests. For APIs handling sensitive data (like financial or health information), go for stateful mode.

This method offers more granular control over access to protected resources (scopes and expiration) compared to bearer authentication. The downside is moderate complexity due to the various roles and redirection flow.

It’s worth the extra effort if you need fine-grained authorization or allow API access by third-party applications on your users’ behalf. For example, users might want a calendar aggregator to access their Google calendars. To view events, only read access is needed. To add or modify events, read-and-write access is required. The Google Calendar API supports OAuth 2.0 for these scenarios.

OpenID Connect (OIDC) 👤

OpenID Connect (OIDC) is simply an identity layer on top of OAuth 2.0 and JWTs that helps client applications authenticate users through identity providers (IDPs). Typical IDPs include popular cloud services or identity providers, such as Google and Okta. It even has a discovery mechanism to get details about available providers, including authorization endpoints, supported scopes and claims, and public keys.

Here’s a quick rundown of how it works:

  1. The client kicks off an authentication request by redirecting to a provider’s authorization endpoint.
  2. The provider then authenticates the user (usually with login credentials) and asks for consent to grant the client access to the requested scopes.
  3. If all goes well, the provider redirects back to the client with an ID token (an encrypted JWT containing claims about the authenticated user’s identity). The client might also get an access token to retrieve more user information or protected resources.

This method is more sophisticated than OAuth 2.0 alone because it adds ID tokens and IDPs.

There’s high complexity, but it’s ideal for a single sign-on (SSO) user experience across multiple resources or services. Users only need to log in once through an IDP, creating a seamless experience and centralizing identity management. For example, signing into your Google account lets you access YouTube, Photos, and Drive. External service providers can also configure Google as an IDP.

Mutual TLS 🤝

Mutual TLS is a form of TLS authentication where both the server and client check each other’s identities using digital certificates before chatting securely. The Transport Layer Security (TLS) is the underlying protocol for authenticating both sides and encrypting the data they share.

Here are the main components to make Mutual TLS work:

  • Public-private key pairs: Both the server and client have their own key pair. Only the private key can decrypt messages encrypted with the public key.
  • TLS certificates:  A data file with all the important details to verify an identity, such as the public key, certificate authority, and expiration date.
  • TLS handshake: The process for exchanging and verifying the TLS certificates with the key pairs.

Once the TLS handshake is done, the client can send API requests over the secure channel. The server may use details from the certificate to decide the API scope.

Mutual TLS is super complex though because you have to manage all the public-private key pairs and TLS certificates. Plus, setting up the infrastructure for the TLS handshake and communication isn’t easy.

However, this method is highly secure and used in Zero Trust security scenarios. It’s also great for verifying clients that don’t follow a login process, such as Internet of Things (IoT) devices.

Migrating to another API authentication method

Many APIs start off with a simple use case and pick a straightforward authentication method, such as API key. But as your API evolves and more users hop on, you might need another suitable method, such as OAuth 2.0. Deciding to update your authentication method depends on your API’s needs for functionality, security, performance, user experience, and integration.

To make the switch smoother, here are some best practices to follow.

Create a new API version 📌

Changing the API authentication scheme is a big deal and needs a new API version. Clients will have to update their implementation to use the latest API.

Have a clear migration path 🧭

Announce a detailed deprecation plan to your API clients that includes:

  • Rationale: Explain why you’re making the change.
  • Scheduled brownout dates: During a brownout, requests using the old authentication method will temporarily fail. This helps clients spot and fix any unmigrated authentication calls by triggering alerts on their services.
  • Cutoff date: The day the old authentication method stops working. Avoid setting this near the calendar year-end when support might be unavailable to handle unexpected issues due to holidays.
  • Migration instructions: Steps the clients should take to switch their implementation to use the new authentication method.
  • Authentication migration endpoint (optional): Offer a special endpoint that helps clients by converting the old authentication type to the new one (e.g. an API key to OAuth 2.0 tokens). 
  • API response headers (optional): Include headers in your responses to notify users and servers about your API deprecation plan.

Check out some noteworthy examples: Dropbox API migration and GitHub authentication deprecation.

Manage multiple API versions 🏷️

For the migration, you must maintain two API versions with clear documentation to inform your clients. It’s kind of like remodeling your home while still living in it. Using an API documentation tool that supports versioning lessens the burden.

Let’s take a look at ReadMe, an advanced API documentation tool. It gives you a bunch of version options: main, public, beta, and deprecated. Juggling multiple versions of your API documentation is super easy, just toggle the visibility settings.

A screenshot of the ReadMe version management dashboard. Source: https://docs.readme.com/main/docs/versions

Moreover, the ReadMe Developer Dashboard can display traffic still going to the old API version. You know exactly which clients need a friendly migration reminder.

Furthermore, ReadMe API Reference pages come with built-in interactive authentication. Instead of telling your users how to authenticate, they can try it out themselves in the API playground. You can also mark certain endpoints as deprecated.

Choosing the Right API Authentication Method

So, what have we learned in our API authentication methods walkthrough?

We’ve got a whole toolbox of options 🧰: API key, HTTP authentication (basic and bearer), OAuth 2.0, OIDC, and mutual TLS. Choosing the right one depends on your specific use case. Also, consider the tradeoffs between security and complexity. 

Thinking of changing your API authentication method? It’s totally doable. Just make sure you’ve got a solid plan and a supercharged API documentation tool. Both you and your users will sleep better at night 😴 with a smooth transition.