With the API economy being a key enabler for turning your business or organization into a platform, most organizations have started to roll out APIs. With so many APIs being enabled for both external and internal consumers, layering them has become very important for enterprise architecture. And API led connectivity is the integration approach for connecting and exposing assets that will provide the speed organizations are looking for.
With data breaches now costing $400M or more, senior IT decision-makers are right to be concerned about API security.
With so many layers of APIs, securing APIs need to be thorough not only from one API perspective but from a layering perspective as well. This is where end to end security of the API becomes a top priority.
This article walks you through few key patterns and how to implement them.
There are 3 key patterns for securing APIs with OAuth.
- Scenario A: Application securely calling API
- Scenario B: One layer of API calling another layer of API
- Scenario C: API calling system of records
Scenario A: Application securely calling API
When an application securely calls an API using OAuth, it is not possible for the application to respond to a prompt screen as the application is not a user trying to connect to the API. Below are some scenarios that would play out based on the organization-specific use case.
- Internal applications: client credentials grant (Implicit Grant Type)
This option can be used by applications sitting within an organization’s network. A client is using Client Credentials Grant in OAuth to secure a call API without a prompt.
Step 1: Client applications will be registered in the organization OAuth provider, for example, Azure AD which supports OAuth 2.0.
Step 2: Similar to an API obtaining its credentials, a client will be registered in an OAuth provider and will be issued a client ID and secret with the right permissions mapped against the client application.
Step 3: A client should use the client’s clientID/Secret details along with shared permissions to fetch an access token using client credentials grant flow.
Sample Code block to fetch access token via client credentials flow.
POST /contoso.com/oauth2/token HTTP/1.1
- External applications: JWT exchange
This option is for applications outside the organization domain registered with an external OAuth provider, for example, salesforce OAuth, which supports OAuth2.0 with key pair.
Considering an external OAuth provider does not support client credentials flow, JWT Bearer token flow can be used as an alternative to secure call an API without a prompt.
Step 1: Client application should firstly be registered in an OAuth provider and provide public key from private/public key pair.
Step 2: Client then takes responsibility to generate a JWT and sign it using their private key.
Sample Code block to fetch access token via JWT exchange flow.
POST /services/oauth2/token HTTP/1.1 Host: login.example.com Content-Type: application/x-www-form-urlencoded grant_type= urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJpc3MiOiAiM01WRz...[omitted for brevity]...ZT
- Basic authorization
For applications that do not have support for OAuth 2.0, applications should use the Basic Auth alternative with credentials being encrypted using strong encryption algorithms.
On behalf of flow
Scenario B: One layer of API calling another layer of API
With multiple layers of APIs being build by organisation, below explains how to propagate chain of trust while one layer of API calls another layer of API with out prompt.
- Implicit grant flow
Common scenario is
a. Experience Layer (as documented in API led connectivity) calling Process Layer or
b. Process Layer calling System Layer.
Client credentials flow best suits this.
To propagate the chain of trust from one layer of API to another layer of API On behalf of flow can be used. This allows API to set right permission which is managed per audience & issuer wise.
In this approach, API layer A already has a OAuth token which was used to call A. And when API layer A wants to call API layer B using OAuth, API layer A requests another token to call API layer B, on behalf of the original token that was used to securely call API layer A.
Sample Code block to fetch access token via on behalf of flow.
- Basic Authorization
Not all API layers in an organisation will be OAuth enabled.
Good example for this could be outer layers of organisational API eco system could be OAuth protected. And API layers closer to core systems are not OAuth protected.
This is where API layer terminated OAuth trust and jumps to another Authentication/Authorisation model. In this case jumps from OAuth to Basic Auth with strong encryption algorithms.
Scenario C: API calling system of records
This is where API layers has reached the end of chain and starts to jump to core systems of record, which support various protocols for communication.
- System of Records support OAuth 2.0 token
API layers that call core system of record (System APIs) that support OAuth 2.0 are expected to use OAuth to propagate trust further.
Based on what OAuth provider is supported by the end system, the choice might differ.
If the same OAuth provider is used by the system of records then the same OAuth token can be propagated on behalf of flow.
If a different OAuth provider is used and these are not compatible, the API layer would need to terminate the flow of trust and jump to a system of records OAuth provider mechanism to continue its secure call. Options for API layer are without prompts OAuth call.
- Native protocol
The API layer would need to terminate the flow of trust and jump to a system of records supported security mechanisms to secure the call.
Finally all of the scenarios discussed above have to be treated as the critical path during the design/requirement phase. Having a monitoring capability over this setup would strengthen the security aspects further!