blue puzzle piece

Getting Started – Lesson 5

API Security and Authentication

This post explains basic concepts of API security and authentication and describes some authentication patterns that you’ll likely encounter when using REST APIs. API security & authentication is a complex topic with numerous implementations throughout the world of APIs — it’s impossible for a single post to cover it all! However, having this foundational knowledge should lay the groundwork for you to understand the authentication methodology of whichever API(s) you use.

Why authentication?

Some APIs are wide open — they can be called by anyone and therefore don’t require that callers identify themselves. However, unsecured APIs like this are rare — most APIs limit access only to entities (users or applications) that are known to the corresponding system. Want to call the DocuSign API? You’ll need a DocuSign account. Want to call the Twitter API? You’ll need a Twitter account. Want to call the Microsoft Azure API? You’ll need an Azure account. You get the point…

Any API that restricts access to registered users or applications only will require that each API request identify the entity that’s issuing the request. If an API is unable to authenticate the requester, it’ll reject the request and return an error in response.

API authentication flow chart

Authentication versus Authorization

Before we move on, a quick clarification about the terms authentication and authorization. You’ll often hear these terms in the context of API security, and it’s important to understand the difference between the two:

  • Authentication proves identity. Authentication identifies the user or application that’s issuing an API request.
  • Authorization proves access. Authorization determines the actions that an authenticated user or application has rights to perform.

Authentication patterns

Okay, so the purpose of authentication is to identify the user or application that’s issuing an API request. But exactly how is that done?

Although each API is free to implement authentication in its own way, most APIs follow industry standard when it comes to implementing the methods of authentication that they do support. This is great — because once you understand the various auth patterns, you’ll be able to handle authentication for practically any API you encounter.

Let’s take a look at two of the most common authentication patterns:

  • Basic authentication
  • Bearer authentication

Basic authentication

With Basic authentication, the API request specifies the username (commonly an email address) and password corresponding to the account that’s issuing the API request. This information is specified in the Authorization HTTP header of the request. The API documentation will specify the required format of this information, but it’s usually something like username:password, specified as a base64-encoded string. For example:

Authorization: Basic bG9sUjds47yZQ==

This example shows an HTTP header where:

  • Authorization is the name of the HTTP header.
  • The value of the header is the word Basic followed by a space and then the username:password specified as a base-64 encoded string (bG9sUjds47yZQ==).

To learn about a real-world implementation of Basic authentication, see the Twitter API docs.

Bearer authentication

With Bearer authentication, the API request specifies an API access token that corresponds to the account that’s issuing the API request. This information is specified in the Authorization HTTP header of the request. For example:

Authorization: Bearer ll352u9jujauoqz4gstvsae05

This example shows an HTTP header where:

  • Authorization is the name of the HTTP header.
  • The value of the header is the word Bearer followed by a space and then the API access token (ll352u9jujauoqz4gstvsae05).

But how do you obtain the API access token that’s needed for Bearer authentication? How you go about it will depend upon the type of scenario you’re implementing.

Scenario 1: You’re just trying out an API

If you’re just getting started with an API and want to test out some API requests, you’ll probably want to manually generate an API access token in the corresponding app. The docs for the API you’re using should tell you exactly how this is done.

Generally speaking, this requires logging into the app (via the web UI) as the user who will issue the API requests, then navigating to the settings page where API access tokens can be generated. You’ll follow instructions on that page to generate an access token, and then presto — you have what you need to authenticate API requests. Any API request specifying that access token in the Authorization header will be issued by that user account.

To learn about a real-world implementation of Bearer authentication with a manually generated API access token, see the Smartsheet API docs. The following screenshot shows the API Access page within the Smartsheet app where tokens can be generated and revoked.

Scenario 2: Your app will make all API calls using a single account

Sometimes the app you’re creating can use the same user account for all API calls. For example, maybe you’re creating a reporting app that issues a series of GET requests to an API to retrieve data. In this case, all API calls can be made using a single user account (as long as that account has access to the necessary data).

To facilitate this scenario, you can manually generate an API access token in the corresponding app in the same manner that’s described above. You may choose to create the API access token using your own account — in which case all API requests from your app would be run as you. Or even better — you could create another user account in that system, specifically for the purpose of issuing API requests from your app. It’s best practice to generate the access token within a separate account like this, as that account can live on even if your account is decommissioned at some point in the future. This means that if/when you leave the company, the app you built won’t break!

Scenario 3: Your app needs to make API calls as the current user

In some cases, your app will need to issue API calls to another system as the current user.

For example:, let’s say you’re building an app that helps realtors manage their real estate transactions and uses DocuSign to send documents for electronic signature. When a user in your app sends documents to their clients, your app calls the DocuSign API to facilitate the sending. You’ll need to obtain an access token from DocuSign for that user, so that the DocuSign API calls that your app issues (including the Create Envelope request that’s used to send documents) can be run as that user. That way, the documents will appear to come from them, not from some generic system account.

But how do you obtain an API access token from another system that enables access to the user’s account there? You’ll use a protocol known as OAuth 2.0. It’s worth noting that OAuth 2.0 provides both authentication (identifies the user account) and authorization (specifies what actions the token can be used to perform).

A successful OAuth 2.0 consent flow goes like this:

  1. Your app asks its current user for consent to access specific types of data and/or perform specific actions in the other system as them.
    • The following screenshot shows an example of this, where Test App 2021 is asking the current user for consent to access their Smartsheet account.
  2. The user grants consent (for the specified scopes).
    • In the following screenshot, the user would choose the Allow button to grant consent.
  3. The other system provides your app with an access token that it can use to issue API requests as that user.
    • This is actually a multi-step process that I won’t elaborate on here. The docs for the API you’re using will provide complete steps for implementing the OAuth 2.0 consent flow.
OAuth 2.0 consent ask (Smartsheet)

Once your app has obtained an API access token using the OAuth 2.0 consent flow, it can issue API requests to the other system as the user who provided consent. Any API request specifying that access token in the Authorization header with the Bearer keyword will be seen as coming from that user account.

To learn about a real-world implementation of Bearer authentication that uses the OAuth 2.0 consent flow, see the DocuSign API docs.

API keys

Up until now, we’ve discussed Basic authentication and Bearer authentication in the context of user-level authentication. That is, how to use these patterns of authentication to issue API requests as a specific user account. But what if you want to associate API requests with an application, rather than with a specific user? Some APIs support this scenario with the use of API keys.

An API key identifies an application — not a specific user account. When you generate an API key, you associate it with a specific application. Then, any API request that specifies that API key is known to have originated from the corresponding application. Depending on the API, the API key may be specified in the Authorization HTTP header, in a custom HTTP header, in the query string of the request URL, or in the body of the request.

To learn about a real-world implementation of API keys, see the Google Cloud API docs.

So there you have it…

…a brief introduction to API security and authentication. This is such a complex topic, we’ve barely scratched the surface of all that it entails. But fear not! The documentation for any API you use should explain its authentication methodology in great detail. If you can leave here knowing the purpose of authentication, and with a basic understanding of Basic auth, Bearer auth, and API keys, you’re well on your way!

Next up, we’ll take a look at Developer Resources.

JSON

stay in the loop

Subscribe to receive email notifications about new content!

Further reading: This site provides the level of technical detail required to understand and use REST APIs in most situations. If you'd like to geek out on these topics further, the internet is full of more in-depth resources!