Lars-Erik Kindblad
Writing about software development, architecture and security

Scaling Microservices Part 3 - Passport Pattern

Many systems consist of tens- or hundreds of services, each providing different functionality. To deliver a given functionality, one service often needs to call n-number of other services. All of these services often depend on common data that must be retrieved from other services. This leads to a complex call hierarchy and potential performance issues, as seen in the diagram below.

Diagram showing a system with complex call stacks not using the passport pattern

Various methods and patterns can be used to solve this problem; in this part, we will see how the passport pattern can be used to solve it.

What Is the Passport Pattern?

The passport pattern is a method where an edge component, like the API Gateway or the topmost service in the call chain, calls one or more services to get the commonly used data across all the different services. In the diagram above, user profile and authorization data are common data used by all the services. These data can then be passed along to the underlying services as part of the request payload. The services can then use the data from the request instead of getting the data from service calls.

Diagram showing a system with complex call stacks using the passport pattern

Authentication Token vs Passport Token

Authentication tokens are often issued by third-party identity services and are stored in browser cookies. They usually only contain a subset of the data in a passport token. The passport token is only available server side. It can contain sensitive data and isn't limited to identity data; it can have any data.

Diagram showing the authentication token and passport token

Things to Consider

When using the passport pattern, there are some things that you need to decide on:

  • What token type to use
  • What token signing algorithm to use
  • How to transfer the passport token between services
  • What component should create the passport token

#1 - What Token Type to Use

JSON Web Token (JWT) is a suitable token type for the passport token. It consists of a JSON payload together with a signature.

Image showing a JWT

#2 - What Token Signing Algorithm to Use

A JWT can be signed using a private secret or a public/private key.

Using a private secret (symmetric) signing algorithm like HS256 is faster, but the private secret must be shared with both the service creating the JWT and the services validating it.

A public/private (asymmetric) key-based signing algorithm like RS256 or ES256 is slower but still preferred in most situations. By using this, only the service responsible for creating the JWT will have access to the private key. The other services will only have access to the public key, which they can use to validate the token.

Diagram showing what services that have access to the private or public key

#3 - How to Transfer the Passport Token Between Services

The passport token can be transferred using the HTTP request header.

#4 - What Component Should Create the Passport Token

Various components and services can create the passport token:

  • Edge components like the API Gateway.
  • The topmost service in the call stack.
  • The Token / Identity Service (STS).
  • The services providing common data.
  • A new new Common Data Service.

Edge Components

Diagram showing passport token generation done by an edge component

Advantage:

  • The passport token creation logic doesn't have to be duplicated; it's in a single place and can be easily modified. However, if there is a breaking change, the services must still be updated to understand the changes.

Disadvantages:

  • It can be more complex to add logic to edge components than to application components.
  • Most developers don't run edge components locally on their development machines. Due to this, the passport token won't be sent along locally.
  • Some trust their edge components less than their services.

The Topmost Service

Diagram showing passport token generation done by the topmost service

Advantages:

  • Easy to add things to the application code.
  • Will work on local development machines since the service will create the token.

Disadvantage:

  • Systems have many services. To prevent duplication of the passport creation logic, a shared library must be made, kept up to date, and used by all the services. However, this library should be made anyway to ensure that the services share a common way to read and validate the passport token.

The Token Service

Diagram showing token generation done by the token service

Advantage:

  • The services usually already have a JWT used for authentication. If the Token Service generates the passport token, then a token with both the identity and the common data can be made. Instead of transferring multiple tokens to the services, one token can be sent along.

Disadvantage:

  • If the common data is unrelated to identity, it might not be architecturally right for the Token Service to have this responsibility.

The Services Providing Common Data

Diagram showing token generation done by the services providing common data

Advantages:

  • The private key is moved from the API Gateway or topmost service to the common data services.
  • Multiple private/public keys can be used if needed.

Disadvantage:

  • The services need to validate and read data from multiple tokens: the authentication token and 2 passport tokens (user profile JWT and authorization JWT).

A New Common Data Service

A new Common Data Service can be made that provides the common passport data by calling the other services common data services.

Diagram showing token generation done by a single common data service

Advantages:

  • Will get a single passport token instead of multiple tokens.
  • The private key is moved from the API Gateway or topmost service to the Common Data Service.

Disadvantages:

  • Performance overhead if the new service must call the other common data sources, unless other scaling techniques are used in addition.

Summary

The passport pattern can help with scaling your microservices. It can be used in various ways, and you need to select the method and variation that match your needs and requirements.