If your business is scaling up, you may find that you deliver many more software applications and APIs than you did originally — all of which will most likely use sensitive and personal data. This data must, of course, be secured. So where do you start and how do you ensure you do this right?
Security Challenges to Consider
It can be challenging to deliver a good security implementation with limited resources that address all the Open Web Application Security Project’s top 10 API security risks. There are many requirements to consider — here are some of the most important:
- Avoiding data leaks and preventing cyberattacks
- Meeting regulatory requirements
- Integrating security features in a simple and scalable manner
Architectural requirements like these need an architectural solution that is designed once and is repeatable across an organization. You must ensure the solution is scalable as your implementation grows so that the same patterns can be used and understood across many teams.
Security Standards Are Important
By using security standards designed and vetted by industry experts, you can establish a high baseline for security. Modern app security standards are based on the OAuth 2.0 family of technologies, which provide good capabilities, including excellent connectivity with other systems and the ability to integrate with most stacks. OAuth provides a mechanism to control which parties can access which information.
Another necessary standard is OpenID Connect, an identity layer that sits on top of OAuth. It allows for verification of an end user’s identity based on the authentication performed by an authorization server. It also allows clients to request and receive information about authenticated sessions and end users.
Creating a Security Architecture
As a baseline, a token-based security architecture is recommended. In a token-based system, your apps — the “clients,” in OAuth terminology — integrate with an identity server and securely communicate with APIs through a reverse proxy that acts as a gatekeeper for access tokens.
Relying on security experts to implement your system is recommended, and for difficult security work, two types of components should be considered:
- An identity server provides an implementation of OAuth standards, dealing with security details including authentication and token issuance.
- Certified security libraries trigger authentication and verify received tokens.
You do not necessarily have to purchase expensive products. Instead, you can get started with free or open source implementations, such as the Community Edition of the Curity Identity Server.
A modern, mature security architecture consists of a few different elements, which work together for the benefit of your applications. Let’s have a closer look at how they contribute to the identity and access management solutions.
Apps use security libraries to integrate with the identity server for user authentication and obtain access tokens. This process occurs in different ways, and each “flow” has its own security benefits, depending on the use case.
After the user has been successfully authenticated, the identity server issues tokens. Tokens define the data the client can access and which operations the client or downstream APIs can perform on that data on behalf of the user. Depending on the requirements, the user may need to explicitly consent to this “delegation” as part of the authentication process.
Think of the access token as the entry ticket to an API. Access tokens carry enough data so that the API can perform adequate authorization. There are two types of access tokens: Lightweight opaque reference tokens and structured by-value tokens.
In a secure architecture, internet clients receive short-lived reference access tokens. The reference token points to the security state stored in the identity server. APIs receive by-value tokens in the form of digitally signed JSON Web Tokens (JWTs) that already contain the security state. The reverse proxy stands in between.
The reverse proxy, such as an NGINX Ingress or a cloud API gateway, is the gatekeeper that prevents the identity server from being directly exposed to the internet. This is good practice because these components connect to sensitive data sources. The reverse proxy hides the internal structure and can also run plug-ins to perform security tasks, which can help to keep API code business-focused.
One such security feature is authorization. As every request goes through the reverse proxy, it can ensure that only authorized requests may pass. As part of the enforcement, it can perform some basic token validation. Further, the reverse proxy can swap incoming reference tokens for JSON Web Tokens that it forwards to the APIs. This approach is called the Phantom token pattern.
In the Phantom token approach, the reverse proxy utilizes the introspection capability of the identity server to retrieve a by-value representation of an access token. The reverse proxy commonly caches results for future requests with the same access token.
Usually, a reverse proxy is already in place in today’s API infrastructure. Consequently, the architecture above does not require any new system but reuses existing solutions.
API Token Validation
After introspection, the reverse proxy forwards the incoming request to the API with a JWT access token that is digitally signed by the identity server. The API must validate the token before using data from its payload. This should be done according to JWT best practices.
If the token is considered valid following the above recommendations and best practices, the API can trust the data received in the JWT. It can process the “scopes” and “claims” into a principal object in memory, which is central for the authorization.
The content of the access token is the result of a contract between the identity server and the API. The API uses scopes and claims for the authorization — thus, the identity server must ensure that the token contains all the data the API needs for proper authorization.
Scopes are a high-level privilege, and claims provide more fine-grained data needed for business authorization. In combination, they help the API determine if the client and user are allowed to perform the request. Study the following example:
Scope: orders_read -> Claim: account-nr : Gives the API instructions to look up the orders for a given
account-nr. The API requires the account-nr to be able to look up any orders. The identity server ensures that the token contains the
account-nr whenever the scope orders_read is requested.
The API can trust that the client is entitled to request the scope in a token because the JWT from the identity server has been cryptographically verified. The API can then simply check for the presence of the required scopes. The API can also ensure that a claim belongs to the user represented by the token and process the request accordingly.
Some industries require APIs to meet more complex rules. So make sure the identity server is flexible enough to issue the scopes and claims needed to meet these requirements.
Using a design pattern like the one above requires only simple code in the APIs and scales well to a microservices architecture, where each API acts as an independent service. By carefully designing the access token, it’s possible to achieve a high level of containment for the services.
APIs can forward access tokens to downstream services. Sometimes, it can be helpful to generate a new token for the downstream service with updated or reduced privileges.
The identity server is the heart of the security architecture. It handles the OAuth 2.0 and OpenID Connect messages for various flows. As part of the flows, the identity server is responsible for authenticating clients and users. Consequently, the server stores secrets, such as passwords and certificates, and integrates with different data sources. Data sources are used for fetching attributes or storing token data. The identity server is, after all, the component that issues confidential tokens to clients and stores related scopes and claims for APIs.
End users interact with the identity server during authentication, which can use multiple factors and also needs to provide a modern and friendly user experience. This experience includes capturing the users’ consent where applicable. The identity server can be relied upon to audit security events and grant privileges. By auditing scopes and claims, the identity server provides a secure record of who has accessed what data over time, in line with compliance requirements.
At any software company, multiple APIs and clients will be developed, often with different security requirements. Therefore, choose a product that offers a rich set of customization and integration options. This includes support for various data sources and authentication methods but also branding of screens and rich token issuance behavior. Remember that requirements can change. Thus, the identity server must be flexible and able to support future use cases.
The security architecture stands and falls with the identity server. Therefore, it must support high availability and zero downtime upgrades to avoid any outage.
Key Components of Token-Based Architecture
To get started with a secure architecture for identity and access management, implement a token-based architecture with the following key components:
- An identity server that is responsible for authentication and token issuance
- A reverse proxy that protects APIs and the identity server
- APIs that rely on digitally verifiable claims for authorization
- Certified libraries that implement lower-level security for APIs and clients
Using a tool like the Community Edition of the Curity Identity Server, you can easily create secure end-to-end solutions at no or low cost, enabling your teams to spend more time on core business features.