APIs are becoming the main interface for interacting with many things, from enterprise services, public services offered over the internet to physical devices. As there can be a large number of APIs deployed within an organization and there can many consumers for those APIs, properly authenticating all parties involved in API-based interactions is a major step of API security. This article looks at different authentication scenarios related to APIs and possible implementation approaches.
First, let’s look at main entities involved in a simple API deployment (Figure 1). We have a set of services that need to be exposed as APIs. These services can be back end services deployed in on-premise data centers, service offered by a device or cloud services. Then we have client applications that need to consume services. These can be mobile applications, web applications, IoT devices, partner systems, etc. Some client applications will be used by human users (e.g. mobile apps and web apps) and some may not have an associated human user (e.g. IoT devices). API layer sits in between client applications and services, forming a proxy for all service requests. Details about organization’s users are stored in its identity provider (IDP). API layer uses IDP to authenticate users and access user information. IDP can be built into the API layer or can be an external IDP.
As human users, devices and systems access services via APIs, API layer can identify who is accessing services. Moving the authentication part to the API layer can also free up services from performing such tasks in most cases. Furthermore, API layer can provide a single authentication experience to all users by hiding possibly heterogeneous authentication mechanisms required for back end services.
In the following sections, we examine different authentication scenarios related to APIs.
Assume that a company named HMart is developing a web portal for its employees to access company’s facilities (Figure 2). This web portal needs to invoke APIs of multiple systems such as HR system, building management system, parking slot allocation system, etc. In this scenario, the client application is HMart portal. Application users are HMart’s employees, whose details are stored in HMart IDP. Therefore, in this scenario, it is possible and useful to authenticate both the client application and users.
Assume that there is a partner company named DDStore, which has an online shopping app. HMart is a supplier of DDStore. DDStore’s shopping app needs to access HMart product catalog via an API (Figure 3). In this case, DDStore shopping app is used by its customers and this customer data is stored in a DDStore IDP. Usually, HMart only needs to know that DDStore shopping app is accessing its APIs, rather than knowing each customer who is using the shopping app. Furthermore, DDStore would not be willing to share its customer data with HMart. Therefore, in this scenario, it is sufficient to authenticate only the client application (i.e. shopping app) at the API layer. Authentication of users will be performed only by the DDStore shopping app using DDStore IDP.
Consider a scenario where a sensor installed in one of HMart warehouses sending temperature values periodically to HMart warehouse management system via an API (Figure 4). Another scenario would be HMart reporting system accessing HMart building management system to get building occupation data via an API. In these scenarios, regardless of whether the client is an internal system or an external system, there is no user associated with it. Therefore, from the authentication perspective, we can consider this similar to Scenario 2 and authenticate only the client system.
In scenario 2, we considered a situation where two separate organizations interact using APIs. In that scenario, IDPs are completely isolated from each other and the API layer only considers DDStore as the client, not its individual users. However, there could be use cases where two organizations are maintaining separate IDPs, yet need to authenticate individual users as well. As an example, we can assume HMart to have a head office and multiple regional offices, each maintaining its own IDPs. Now let’s consider a use case where a head office employee visits a regional office and attempts to use its warehouse management system’s web portal. In this case, it may be useful to authenticate both the client application and the user, although the user is not registered in the IDP associated with the API layer.
So far, we have looked at situations where clients authenticate with the API layer. However, there could be situations where the API layer may also have to authenticate with back end services. One example is when the API layer needs to call a cloud service such as Salesforce or Google Sheets. Even within the same organizational network, it is useful enforce authentication mechanisms for each system as it enables administrators to track and control service interactions. For example, HMart parking slot allocation system may have an authentication mechanism to authenticate any application that uses its services. Furthermore, authenticating users with back end services and passing user information to them could be useful for enforcing fine grained access control at those services (e.g. only the users with manager role and working at the administration division can access parking slot usage data).
In this section, we will discuss different authentication mechanisms and how they can be used to implement authentication scenarios discussed above.
Authenticating client applications
First we will look at methods for authenticating client applications. These methods can be used to implement scenarios 2 and 3, which require only the client application to be authenticated. Furthermore, these methods can be used in conjunction with different user authentication methods discussed in the next section to implement scenarios 1 and 4, which require both the client application and the user to be authenticated. Scenario 5 requires API layer to be authenticated with back end services. Below methods can be used for that scenario by considering API layer as the client application.
Client certificates: We can create a certificate for each client application containing the client identifier and other required details, and sign it with a certificate trusted by the API layer. Client application has to send its certificate with each API invocation so the the API layer can validate the certificate and identify the client.
API keys: Each client application can register with the API layer and obtain a unique key to represent itself. This key can be just a string or a meaningful text signed with a trusted certificate. In either case, client applications have to send their API keys with each API invocation and the API layer can correlate the API key to a registered application.
OAuth 2.0 tokens (client credentials grant type): Client credentials grant type only requires client application identifier and client secret for generating an OAuth token. Therefore, when a client application sends such OAuth token with API invocations, API layer can uniquely identify the client. In this case, user is not identified as user credentials are not used for generating OAuth tokens.
Now we can look at methods for authenticating users. These methods can be used alone or in conjunction with client application authentication methods to identify both the client application and the user as required by scenario 1 and 4.
HTTP Basic Authentication: HTTP basic authentication can be used to send user credentials in HTTP headers with each API invocation. Therefore, this method can be used to authenticate users with the API layer. Furthermore, if we represent an application using some user credentials, it is possible to use basic authentication for authenticating client applications as well. The downside of this method is that user credentials can be exposed to unintended parties if TLS is not used.
HTTP Digest Authentication: HTTP digest authentication sends hashed value of user credentials of with each API invocation. Therefore, similar to HTTP basic authentication, this can be used for both user and client application identification. However, the risk of exposing user credentials is eliminated as hashed values are used.
OAuth 2.0 tokens (authorization code grant type): Authorization code grant type requires both client application credentials and user credentials when issuing an OAuth token. Therefore, when such tokens are sent with each API invocation, API layer can identify both the client application and the user.
Authenticating users from external identity providers
In scenario 4, HMart head office and each HMart regional office have separate identity providers. API layer of each of HMart regional office only trusts its identity provider. Now the problem in scenario 4 is that an employee belonging to HMart head office wants to access a warehouse API deployed in a HMart regional office.
As this is the same organization, regional office IDPs can trust the head office IDP. One way of establishing this trust is to import head office IDP’s certificate into regional office IDPs as a trusted certificate (Figure 7). Then the head office user can first obtain a security token (e.g. containing user name and other relevant details) from head office IDP (as the user is in it’s user store), signed by head office IDP’s private key. Now the user can present this security token to regional office IDP and exchange it for a security token recognized by regional office API layer. Then this new security token can be used for the regional office warehouse API invocations. Some implementations of this approach is JWT token exchange and SAML token exchange, where JWT or SAML tokens obtained from external IDP’s are exchanged for OAuth 2.0 tokens recognized by the API layer.
Another approach for enabling trust relationship among IDPs is to configure the head office IDP as a federated identity provider of the regional IDP (Figure 8). That means, when a user tries to authenticate with the regional office IDP, he also gets the option for authenticating via the head office IDP. If a user selects head office IDP option and successfully authenticates with it, regional office IDP will trust that authentication and issue a security token valid for regional office API layer. Common implementations of this approach are OpenID Connect federation and SAML federation.
Authenticating with back end systems
Approaches described above can be used to authenticate API consumers with the API layer and can be used to implement scenarios 1 to 4. Similar to the API layer, back end services may also want to authenticate either client applications, users or both, which is the problem considered in scenario 5. Note that in this scenario, client application is always the API layer. We can use any of the client application authentication methods discussed above to authenticate the API layer with back end services (i.e. client certificates, API keys or client credentials based OAuth 2.0 tokens). It is also possible to represent the API layer as a user account in back end services and use user credentials based authentication mechanisms (e.g. HTTP basic authentication) to authenticate the API layer. Similar to the way we can embed tokens/credentials in client applications, we can embed credentials in the API layer as well.
Now we can consider authenticating users with back end services. One method is to send user credentials or hashed credentials to back end services. However, as back end services and the API layer may have different user stores, two sets of user credentials may have to be used. Further, back end service user credentials have to be passed through the API layer, which can expose them unless those are encrypted. Therefore, a better approach for authenticating users with back ends is to have a trust relationship between API layer and back ends. Then for each request, API layer can create a token containing user details and sign it with API layer’s private key. As back end services trust API layer’s certificate, those services can validate the user details sent in the signed token and authenticate the user. This method can be realized by generating JWT tokens signed by API layer’s private key and sending them to back end services.
The overall picture
We have looked at different API authentication scenarios and possible implementation methods. Now we can see how these methods can be combined to achieve better API security from the authentication perspective.
Above diagram shows interactions among HMart head office, HMart regional office and DDStore (partner) systems. API calls are indicated in blue color arrows. Client to API layer authentications are marked in red color arrows. First, let’s take the scenario of Jane (HMart regional office employee) accessing the warehouse portal. Jane is authenticated with the regional office IDP and a API token is issued to the warehouse portal. Warehouse portal uses this token to invoke warehouse management system’s APIs via the API layer.
Now we can consider the scenario where Peter (HMart head office employee) uses the warehouse mobile app. Regional office IDP is configured as the IDP of the mobile app. Therefore, Peter is directed to authenticate with the regional office IDP. However, as the head office IDP is configured as a federated IDP, Peter can select that option and authenticate with the head office IDP. Once authenticated, regional office IDP recognizes that and issues a API token to the mobile app, which can be used to invoke warehouse APIs.
Finally, we can consider the scenario where Mark (DDStore customer) uses the DDStore shopping portal to buy products. Shopping portal first authenticates Mark with DDStore IDP. DDStore IDP issues an API token for the shopping portal to be used for relevant internal API invocations including the inventory management API. However, DDStore inventory management system needs to invoke HMart’s warehouse API to order products that are not available in DDStore stocks. Inventory management system gets an API token from the HMart regional office IDP using the client credentials grant type. In addition to token based authentication, HMart enforces certificate based client system authentication in order mitigate risks of token leakages. To enable this, inventory system’s certificate is associated with HMart API layer as a valid client certificate. Therefore, DDStore inventory system sends both API token and its certificate (via mutual TLS) to securely access HMart APIs. All API layers can use any combination of basic authentication, API keys and client certificates to authenticate with corresponding backend systems as discussed earlier.