Envoy: Decode JWT and put “value” into a request header

Created on 17 Jan 2020  ·  5Comments  ·  Source: envoyproxy/envoy

Similar to https://discuss.istio.io/t/question-decode-jwt-and-put-sub-into-a-request-header/1213

Looking to do rate limiting off values from JWT

Looking to decode a JWT and put fields into headers; which can then be used by the rate_limit filter when setting descriptors.

Is the only way to approach this in Envoy using Lua scripts?

Thanks

question

Most helpful comment

So I have ended up with

  - name: envoy.filters.http.jwt_authn
    config:
      providers:
        jwt_auth:
          ....
          payload_in_metadata: jwt_payload

And then I can read it with

  http_filters:
  - name: envoy.lua
    typed_config:
      "@type": type.googleapis.com/envoy.config.filter.http.lua.v2.Lua
      inline_code: |
        function envoy_on_request(request_handle)
          local meta = request_handle:streamInfo():dynamicMetadata()
          for key, value in pairs(meta) do
            request_handle:logInfo("extract dynamicMetadata key: "..key)
            request_handle:logInfo("extract dynamicMetadata value: "..value.jwt_payload.usr)
          end
        end

Those logs work; and I'm setting the value into a header with

request_handle:headers():add("jwt-extracted-user", value.jwt_payload.usr)

And pass to the ratelimit service with

rate_limits:
- actions:
   - {request_headers: {"header_name": "jwt-extracted-user","descriptor_key": "jwt-extracted-user"}}

All 5 comments

If specified, jwt_authn filter put the whole payload into the request header.
If you want to use specified payload field, you can use dynamicMetadata. Jwt_authn stores the payload into dynamicMetadata (if specified), other filters can use its fields directly. This is how Istio RBAC filter use it.

Great; thank you very much - I will look into leveraging those features.

So I have ended up with

  - name: envoy.filters.http.jwt_authn
    config:
      providers:
        jwt_auth:
          ....
          payload_in_metadata: jwt_payload

And then I can read it with

  http_filters:
  - name: envoy.lua
    typed_config:
      "@type": type.googleapis.com/envoy.config.filter.http.lua.v2.Lua
      inline_code: |
        function envoy_on_request(request_handle)
          local meta = request_handle:streamInfo():dynamicMetadata()
          for key, value in pairs(meta) do
            request_handle:logInfo("extract dynamicMetadata key: "..key)
            request_handle:logInfo("extract dynamicMetadata value: "..value.jwt_payload.usr)
          end
        end

Those logs work; and I'm setting the value into a header with

request_handle:headers():add("jwt-extracted-user", value.jwt_payload.usr)

And pass to the ratelimit service with

rate_limits:
- actions:
   - {request_headers: {"header_name": "jwt-extracted-user","descriptor_key": "jwt-extracted-user"}}

@qbrent thanks for sharing your config. It will definitely help others.

@qbrent - That config was extremely helpful! Thank you so much for sharing!

Was this page helpful?
0 / 5 - 0 ratings