Combine existing security concepts and best practices together and design more secure distributed applications.
Part 1 of this two-part series discussed what services and microservices are, the role of APIs and API gateways in modern application architectures, the importance of user-level security context, and end-to-end (E2E) trust. Now part 2 covers authorization (authZ) and different ways of handing it across microservices, what authentication (authN) and authZ protocols to use, what to do when an API is invoked by applications and services outside its trust boundary, additional security policies to consider beyond authN and authZ, logging and monitoring considerations, and how group policies can help build a more secure API and microservices based application.
Some exposure and previous knowledge of APIs and microservices-based architectures help you better grasp of the security aspects discussed. However, it is not necessary.
Take about 30 to 45 minutes to read both parts of the series. Part 2 should take about 15 to 20 minutes.
The need for AuthZ
Part 1 discussed authenticating the end-user and enforcing the required security policies across microservices of an application at the API gateway. In addition, each microservice may have specific authZ requirements. For example, in an online banking application, a microservice handling bank accounts should only allow read operations to a checking account for a user with a basic authentication context. But the checking account should also allow the user to perform both read and write operations with a 2FA authentication context. The security token service can evaluate the information about the service or resource requested (typically the HTTP URL location of the target service or resource), the scope or type of request, as well as the user’s security context and issue a security token that represents the authZ issued, including valid claims that are made. The set of claims can include the end-user and issuer’s identities, identities of specific consumers, expiration time, and more.
Consider an architecture where a token-exchange service is used to obtain a security token for each request as shown in the following flow diagram. The service can handle authZ aspects, such as whether a specific request type (for example, READ) under a given user-level security context is allowed for the requested service or resource, and it can add this information as valid claims and scopes in the token.
Figure 1: A microservices application architecture with a token-exchange service
The microservice receiving the security token along with the service request verifies the authenticity of the token to ensure it is issued by a trusted service, and then provides the functionality requested by the sender based on the valid authorized claims and scope. If there are additional microservices required to complete the invocation, the token-exchange service is used to obtain a new security token that can be used by the downstream microservice with the appropriate protocol, claims, and scope.
If a single E2E trust token is issued at the API gateway for the entire journey across one or more microservices and no token-exchange service is used downstream, each of the microservices across the call chain must handle all authZ related aspects. Then each microservice must be configured with the appropriate authZ policy, and ensure they are enforced correctly. Although this model removes the need to get a new security token each time, central handling of authZ and using a token-exchange end-point allow for more flexibility and better access control (as discussed in part 1).
What authN and authZ protocols can I use?
You can also use the SAML protocol for API security, and it supports both authN and authZ. SAML gained popularity with the rise in adoption of web services inside organizations and became the standard of choice for service-oriented architectures. However, due to its heavy nature and SOAP requirement, external RESTful HTTP based APIs opted for the lighter OAuth 2.0 and OIDC protocols.
Invocation by external applications and services
In some cases, to gain access to a specific function or resource (transparently provided to the user as part of the application that is accessed), an application might need to invoke a microservice provided by another application. For example, a mash-up microservice in an online banking application that presents a single view of all of the user’s account balances including chequing and mortgage accounts will need to obtain this information from separate core banking and mortgage systems respectively.
The mortgage application’s microservice is invoked by the mash-up microservice (in this case the online banking application) that resides in another application trust-zone where end-user authentication has already been performed. Because the mortgage application might not use the same IdP (Identity Provider) as the online banking application (and the goal is to not require the user to go through “heavy” authentication again), there needs to be a mechanism to pass the user’s security context and valid claims in a way that is usable by the requested microservice within the mortgage application.
In addition, the security token issued by the online banking application’s security token service proves that the user has successfully met the conditions required by the security policies of the online banking application. However, the mortgage application might have different security policy requirements that need to be satisfied.
In this situation, some form of trust needs to be established between the two applications’ trust zones to allow verifying the authenticity of the claims as well as the user’s security context that is presented by the security token in the request. You can enable the verification of the token’s signature by the security token service of the called application, and by issuing a new token that can be verified by the microservices of that application. The requested microservice’s API gateway can also enforce any additional security policies that are required before the request is passed downstream.
Without central handling of these activities by an API gateway and a security token service, each microservice would need to be able to have a trust relationship with external consumers, which would result in a very complex and unmaintainable architecture.
Unless it is specifically indicated that a given security policy has already been satisfied by the trusted caller, all required security policies should be enforced by the API gateway of the called application. You cannot always trust that external applications have performed the required security checks, therefore a defense-in-depth strategy should be followed where security is applied at all layers.
Should I care about other security issues?
So far, this article focuses primarily on the enforcement of security policies related to authN and authZ concerns. In addition to acting as central a point of such enforcement, the API gateway should also apply other security policies. Consider the following options:
- Rate-limiting prevents calling of an API more than the allowed number of times for a given period by a specific consumer.
- JSON threat protection protects against malicious input in the JSON payload that results in an attack.
- XML threat protection protects against malicious input in the XML payload that results in an attack.
- Other custom policies centrally address applicable web application security threats.
Rather than each development team creating separate policies, the teams should be able to configure and apply required security policies centrally at the API gateway as needed. This approach eases the development process and ensures consistent enforcement. You still might need to develop custom policies to meet specific needs in case they do not already exist.
Don’t forget to log, monitor, and detect
As with all security architectures, detective controls such as logging and monitoring play an important role as well. Each API needs to log all important events including security-related ones and send the data to a central system for further correlation, analysis. and detection of potential security concerns.
It’s important to record security related events, such as a success or failure of compliance to a specific policy, for further analysis and threat detection. Also, collecting information like how many times end-points are invoked and response times, can assist your team in both preventing denial of service and in better profiling the application and system.
To help with fraud detection, APIs can act as instruments to provide data about the specific device and the location that accessed the API. This information allows detection of scenarios that match a specific fraudulent access pattern.
Apply group policy
Grouping related objects into a single unit and applying configuration values or policies across the group is not a new concept. This approach helps you consistently apply those values and policies to the given set of objects in that group. The same principle is applicable to the microservices of an application. Those microservices and their APIs that address a particular business need should be grouped together and presented to developers along with a service plan and set of policies that apply to that group.
For example, consider a set of APIs that provide data in XML format and that are used to build an internal application for account servicing by staff. These APIs require an authentication policy that integrates with the corporate AD, as well as XML threat protection and a rate-limiting policy that focuses on inside initiated access. Another set of APIs use JSON as a data format and are used to build an external application for customers to perform Internet banking. These APIs require an authentication policy that uses the customer data repository (for example, LDAP), enforcement of JSON threat protection, and rate-limiting designed for external use-cases.
After all security policies applicable to the group are successfully enforced, access is provided and limited only to specific microservices or resources within the group, which is indicated by the security token. In cases where individual microservices have additional security policy requirements over and above the group policies, handle the custom policies either at the API gateway along with the security token service, at the token exchange service, or at the microservice itself.
Modern API and microservices-based applications are often distributed and communicate over networks. But it is important that the same level of security assurance is present as in monolithic applications. API gateways help with consistent enforcement of security policies across the microservices of an individual application and can assist with handling authZ related aspects.
It is also important to have user-level security context and E2E trust across the entire journey, in addition to service level trust among the microservices of an application. You can use protocols such as OpenID Connect, OAuth 2.0, and SAML to facilitate authN and authZ, and aid in designing a system that handles security at the right place and the right time and guarantees end-to-end trust across the entire journey.
This article also covered why you should apply other security policies beyond authN and authZ (for example JSON threat protection and rate limiting), the importance of appropriate logging and monitoring, and use of policies at group level in order to build a more secure API and microservices based application.
In summary, take the following key security concepts into consideration when you design and implement microservices and API-based applications or services:
- Maintain user-level E2E trust across the entire journey.
- Ensure authZ is enforced at the right place with the right level of granularity.
- Group your APIs and use an API gateway to apply configurable security policies consistently.
- Don’t forget to log, monitor, and detect.
- Follow a defense-in-depth strategy, and add security at all layers.
“OpenID Connect Core 1.0” by N. Sakimura, J. Bradley, M. Jones, B. de Medeiros, and C. Mortimore:
“The OAuth 2.0 Authorization Framework” IETF RFC 6749, by D. Hardt (Ed.):
“Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0”, Scott Cantor, John Kemp, Rob Philpott, Eve Maler, Eric Goodman
How Mature is Your DevSecOps?
Our comprehensive DevSecOps Maturity Assessment covers 8 key phases of DevSecOps practices, 29 questions in total.
By evaluating your team on each capability, you can determine if your DevSecOps maturity level is early, intermediate, or advanced. Your assessment includes a custom report that provides your overall maturity as well as detailed recommendations you can take to enhance your security posture.