Setup OIDC Filter Chain

There are four main filters that can be used to construct an Open ID Connect (OIDC) filter chain:

  • Ensure Variables

    • This filter checks the existence of a request attribute (header, cookie, etc.) and will copy/move it to the next filter in the chain.

  • OIDC Validation

    • This filter does online validation of an access token by calling the /userinfo endpoint. Note that the response of the /userinfo API is JSON containing user info, not JSON Web Token (JWT) so if there is a need for an ID token, it needs to be acquired via OIDC Authentication filter.

  • OIDC Authentication

  • Envoy JWT Authentication

    • This filter does offline verification of a JWT (e.g. ID token) using a specified JSON Web Key Set (JWKS). It verifies the signature, audience, and issuer as well as time restriction such as expiration and nbf (not before) time. If the verification fails, the request is rejected.

The following filters may appear required for our OAuth/OIDC flow but are used for very specific cases:

  • OAuth

    • This is a legacy OAuth filter that requires openid scope and id_token.

  • JWT Security

    • This filter is tightly coupled with Grey Matter JWT Security service.

Basic Implementation

In this section, we'll cover the layout for a mesh which contains one Edge proxy, one web application with UI accessed via browsers, and one API service which return JSON responses to be consumed by frontend applications.

Image of OIDC Filter Flow

Edge Proxy

  • In a Grey Matter deployment this is simply our sidecar used for edge traffic. It allows all traffic to go through the specified Listeners into the OIDC filter chain.

Application Sidecar Listener

  • OIDC Validation filter checks to see if a request contains an access token in a specified location.

    • If so, validate the token with Identity Provider (IdP) by calling the /userinfo endpoint and optionally store the response JSON into a specified location. If validation fails, remove the access token from the request so that the following filter can process as if the request did not contain an access token.

    • Otherwise let the request go through.

  • OIDC Authentication Filter checks to see if a request contains an access token in a specified location

    • If so, there is nothing more to do.

    • Otherwise check whether an access code exists in this request.

      • If so, exchange the access code for a token with IdP.

      • Otherwise initiate the authentication process with IdP by redirecting the user to a login page.

API Service Sidecar Listener

  • Ensure Variables filter ensures that access tokens that are spread out across multiple request attributes, like a bearer token in a header, a cookie, etc., are moved to a consistent location. This alleviates the need for subsequent filters to check multiple request attributes. If a token is not found, the request is rejected.

  • OIDC Validation filter validates the token with IdP by calling the /userinfo endpoint and optionally stores the response JSON into a specified location. If validation fails, the request is rejected.

Enhanced Implementation

The above implementation works for mesh with a small number of services. However, it requires each and every application/API listener to be aware of OIDC configuration which is cumbersome. The second implementation uses a "gateway" proxy which contains two separate listeners and domains - one for application route, the other for API service route.

Image of enhanced OIDC filter chain at the edge

Edge Proxy

  • It allows any traffic to go through, but using a string pattern match, it splits the traffic into two routes: one for /app and the other for /services, This edge proxy can certainly be omitted by a use of different subdomains/ports for application traffic and API traffic, etc.

Gateway Proxy

Gateway proxy is an instance of the gm-proxy with two listeners and domains. Why two domains? Because a domain can be responsible for one port. When we "split" the traffic into two, /app traffic gets directed to one port (e.g. 8080) of the gateway proxy while /services traffic goes to another port (e.g. 9080).

App Listener & App Domain

This set of listener and domain is responsible for localhost:9443/app traffic. The filters used by the listener are the same as the basic implementation's application sidecar listener.

API Listener & API Domain

This set of listener and domain is responsible for localhost:9443/services traffic. The filters used by the listener are the same as the basic implementation's API service sidecar listener.

Considerations

  • Online validation using OIDC Validation Filter adds an API call to IdP for every single request you serve. If you just need to quickly check whether an ID token (or any other JWT)'s signature, you can use Envoy JWT Authentication.

  • Carefully consider ways to reduce traffic back to IdP. Do static assets for the UI (CSS, images, etc) really need to be protected? Is there a way to cache the validation results so that we only need to ask IdP every 5 minutes, for example?