How DevSecOps Teams Should Approach API Security
Software organizations need to store data and expose it over the internet to user-based applications. The standard way to manage this is to host APIs. In the following diagram, API endpoints are called by both web and mobile clients. APIs are usually also broken down into manageable codebases, sometimes called microservices, which then call each other.
These components are likely familiar to anyone working in software, from business owners to developers, DevOps and compliance staff. Yet in my experience, it is common for these roles to lack a unified vision on how they approach API security. Therefore, in this post, I will provide a recommended API security setup that benefits all parties involved.
To secure APIs, you must send a message credential with every API request. The most secure way to protect your data is to design this credential with minimal privileges, based on end-to-end client and API flows. The credential must be unforgeable and sendable from any type of client. The JSON Web Token (JWT) format meets these requirements.
The following example shows one possible financial use case: An app sends a token to an API, which forwards it to other APIs. The token restricts access to a particular user and payment transaction. The token is locked down in business terms and is, therefore, more secure than an infrastructure-based credential, such as a client certificate:
The ability to lock down access according to business rules is the primary security behavior of the OAuth 2.0 authorization framework. On every request, the API must cryptographically verify a JWT access token, after which the API can trust the values contained within the token, which are called claims. In this example, APIs could use the received transaction_id claim to restrict access to the single payment transaction. More commonly, APIs filter resources according to business rules based on the user’s identity.
Access tokens issued to each client can be designed differently based on that client’s end-to-end API flows. APIs use token sharing to forward access tokens to each other so that the user identity and claims flow securely. Each API then implements authorization using the received claims. This is more secure than solutions that receive a user ID in an encrypted cookie, where the API always allows the user’s full privileges.
Using tokens in this way provides a zero trust API architecture, where APIs do not trust each other. Instead, they only trust the token issuer, which in OAuth 2.0 is the authorization server. A third party provides this specialist component, and using one should give the richest security capabilities for applications and APIs.
This article’s main focus is DevSecOps, so next I will discuss how this API architecture affects security-related roles within an organization. The main behaviors, and the benefits of a token-based architecture, are most apparent once the essential requirements from all DevSecOps stakeholders are understood.
When using OAuth 2.0, frontend developers don’t have to deal with the complexity of user authentication. Instead, logins are implemented using a code flow. This involves redirecting the user to authenticate via the authorization server, which provides many ways to authenticate users. The party providing the authorization server should continually add support for the most cutting-edge authentication options. However, frontend developers need to understand the moving parts, including OAuth 2.0 messages, expiry events and error conditions. Therefore they must learn some OAuth troubleshooting skills.
Meanwhile, both developers and testers need productive ways to get user-level access tokens for test users so that they can send sample API requests. There are various options here, such as using online tools to run a code flow or using mock OAuth infrastructure. The end result should be a productive setup where APIs can easily be supplied with an access token, and then be validated using a token-signing public key downloaded from the authorization server:
Security and compliance teams have their own requirements, which are typically captured by architects when designing API solutions. These span areas like API hosting, browser security, managing personal data, auditing and regulations. The authorization server provides ways to externalize some of these difficult requirements, such as privacy and consent, from applications and APIs. Security teams should also have an awareness of OAuth 2.0 secure development best practices for APIs and clients.
The security team should first ensure that the token-based architecture meets confidentiality requirements. Access tokens delivered to APIs should use the JSON Web Token (JWT) format, yet since these are easily readable, they should not be returned to internet clients. To ensure token confidentiality, the preferred option is to use the phantom token pattern. This involves clients receiving opaque access tokens, which reveal no sensitive data. When APIs are called, an API gateway can introspect the token and forward a JWT to APIs. The end-to-end flow does not add any complexity to API code or require APIs to manage their own crypto keys:
Some organizations use an entitlement management system, such as Open Policy Agent, to centralize authorization. Doing so gives the security team the best visibility into which parties access important business resources. APIs using a token-based architecture integrate well with such systems, since the access token serves as a policy information point (PIP) that can be sent to a policy decision point (PDP), either from the API gateway or the API itself:
In an OAuth 2.0 architecture, APIs and user applications outsource all of the low-level security, including key management and user credentials, to the authorization server. Over time, this component, therefore, includes many intricate security settings. The DevOps team is most often responsible for maintaining its high availability and correct production configurations.
The authorization server should be considered a specialist API, hosted right next to the organization’s APIs. Doing so provides the best performance and allows control over which endpoints are exposed to the internet. DevOps teams should also understand how to de-risk authorization server deployment and upgrades. They should use an OAuth 2.0 parameterized configuration created only once, after which the same binaries and configuration are simply promoted down a pipeline.
Once the token-based architecture is live, DevOps teams need a productive way to manage Day 2 operations for both APIs and the authorization server. This should include dashboard integration, auto-healing, auto-scaling, alerts and useful technical support logs.
DevOps teams often implement security jobs related to the API gateway. An example might be implementing intelligent routing of API requests, such as to the user’s home region, to meet data sovereignty restrictions identified by the security team. The following diagram shows an American user being re-routed to the correct region, based on a claim in the access token, to ensure that the user’s transactions are stored in the United States:
Implemented correctly, an OAuth 2.0 token-based architecture provides a complete zero trust solution for APIs. The best solutions require cross-team collaboration to meet the crucial requirements of all DevSecOps roles. Business owners can then deliver digital services with future-facing security. This solution should offer multiple user authentication methods and first-class interoperability with external systems.
Since OAuth 2.0 requires a distributed architecture, teams often must learn new best practices and put in place productive technical setups. Developers can start by following solid standards-based learning resources like the Curity Guides. The security components you choose are also important. Use an API gateway with good support for the intelligent processing of API requests. Also, verify early that the proposed authorization server has up-to-date support for standards and is extensible. This will enable you to deliver the right claims to APIs and customize user authentication when required.
This article has summarized the core setup needed to implement a modern token-based architecture. Once the correct separation is in place, you can meet all of the main requirements for all DevSecOps roles. The architecture will then scale to many components and other security use cases. The following links provide further related details: