Helpful Badger in the wild

Helpful Badger

Imagining the possibilities

JWS Signature Validation with Envoy

Learn how to validate JWS signatures natively with Envoy

Helpful Badger

4 minute read

Photo by Cytonn Photography on Unsplash

Getting Started with Envoy & Open Policy Agent — 06 —

JWS Signature Validation with Envoy

This is the 6th Envoy & Open Policy Agent Getting Started Guide. Each guide is intended to explore a single feature and walk through a simple implementation. Each guide builds on the concepts explored in the previous guide with the end goal of building a very powerful authorization service by the end of the series.

The source code for this getting started example is located on Github. ——> Envoy & OPA GS # 6

Here is a list of the Getting Started Guides that are currently available.

Getting Started Guides

  1. Using Envoy as a Front Proxy
  2. Adding Observability Tools
  3. Plugging Open Policy Agent into Envoy
  4. Using the Open Policy Agent CLI
  5. JWS Token Validation with OPA
  6. JWS Token Validation with Envoy
  7. Putting It All Together with Composite Authorization
  8. Configuring Envoy Logs Taps and Traces
  9. Sign / Verify HTTP Requests

Introduction

One of the HTTP filters available is the JSON Web Token filter. It is lines 14 - 27 highlighted below. You an specify any number of providers. For each provider the developer specifies the desired validation rules. In our case we have 3 tokens that we will be validating. For each we specify:

  • The issuers and audiences that must be present. Just like with Open Policy Agent audiences, the requirement is that the specified audience is matches one of the audiences in the array.
  • The from_headers property tells Envoy where to find the JWS
  • The forward property specifies if the token should be forwarded to the protected API or if the header should be removed before forwarding. If the JWS tokens can be misused by the protected API then they should be removed.
  • The local_jwks propery allows you to specify the JSON web keyset in the configuration. Another option is to retrieve them from an HTTP endpoint that hosts the key set.

The configuration below shows the properties we just described on lines 22, 25 and 26.

 1static_resources:
 2  listeners:
 3    - address:
 4      ...
 5      filter_chains:
 6          - filters:
 7            - name: envoy.filters.network.http_connection_manager
 8              typed_config:
 9                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
10                ...
11                route_config:
12                ...
13                http_filters:
14                  - name: envoy.filters.http.jwt_authn
15                    typed_config:
16                      "@type": "type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication"
17                      providers:
18                        workforce_provider:
19                          issuer: workforceIdentity.example.com
20                          audiences:
21                          - apigateway.example.com
22>                          from_headers:
23                          - name: "actor-token"
24                            value_prefix: ""
25>                          forward: true
26>                          local_jwks:
27                            inline_string: "..."

The section highlighted below is the rules section. It defines under what conditions to look for and validate a JWS. The match section defines what prefixes to look for. The slash will look for JWS tokens on every URI path. We can specify quite a few rules to determine how many and which tokens we require and under what circumstances. The Official JWT Auth documentation specifies several other options on how to craft logic using and, or and any operations as well as other locations where JWS tokens can be located. There isn’t as much control over what response to return to clients in the case of a failed authentication. OPA lets the developer change chose the HTTP Status code, include messages in the response body add headers etc. Envoy’s built in feature simply returns an HTTP 401 Unauthorized response.


28                        consumer_provider:
29                          ...
30                        gateway_provider:
31                          ...
32>                      rules:
33                        - match:
34                            prefix: /
35                          requires:
36                            requires_all:
37                              requirements:
38                                - provider_name: workforce_provider
39                                - provider_name: consumer_provider
40                                - provider_name: gateway_provider
41                  - name: envoy.filters.http.router
42                    typed_config: {}
43  clusters:
44  ...
45admin:
46...

To see this capability in action, simply run the demonstrate_envoy_jws_validation.sh script. The output is similar to the completed solution from the previous lesson. The script also dumps the Envoy logs to show the information that you have available to trouble shoot issues. Below is a screen shot of the log statements that show Envoy extracting the tokens, performing the validation and logging the result.


Conclusion

In this getting started example, we successfully validated 3 different JWS tokens in a single request and had flexibility to chose where the tokens were pulled from, how many tokens were required and under what conditions those tokens were needed. In our next getting started guide, we will use Open Policy Agent and our identity tokens to make some more sophisticated authorization decisions.

Recent posts

Categories

About

Sharing perspectives.