[Question] Decode JWT and put "sub" into a request header

#1

I’m using the OPA adapter to manage AuthN and AuthZ. Some of my backend services need to know who is making a given request; for example, to populate a created_by column when a given user creates something.

I’m trying to figure out an elegant way of decoding the JWT and putting the “sub” field into a “user” header before the request gets sent to the actual backend service. This way, a given service would simply need to look at the “user” header rather than dealing with parsing the JWT.

Any ideas or recommendations on how this could be accomplished are appreciated.

#2

@liminwang Hi Limin, can you take a look?

#3

Right now, I’m trying to do the same by using some EnvoyFilter.

With some LUA code, you can alter the request / response and so, extract data from token and then inject it inside custom header.

The problem right now is, if I’m not wrong, in this EnvoyFilter, you can’t import lua library, so you have to work from “scratch” with the JWT token.

If some of you have a better idea to do this, I’ll be glad to here it, thanks :star_struck:

#4

I had a similar problem. I forked the opa adapter and modified it to allow returning arbitrary results from the rego evaluation. Envoy’s ext_auth protocol allows the endpoint to return a list of modfied/added headers. I added the result of the evaluation to that list. Envoy then added the headers to the upstream request for me.

#5

Currently either Istio authorization or OPA adapter returns TRUE or FALSE result. It does not modify the headers. If this becomes a popular requirement, we may consider supporting it.

In the JWT case, the original JWT token is passed to the backend. The backend just needs to base64 decode the JWT and get the claim (no need to validate the signature if Istio JWT authentication is enabled). I think this is the only supported way currently. I hope it is not too much burden for the backend.

1 Like
#6

I think a generic JWT to header mechanism that is exposed as a policy would likely eventually need to exist to support simplifying workloads behind the sidecar. Something not specific to any single value (flexible key/value pair for mappings?). Header patterns for are common for proprietary identity proxies, which would also make adapting legacy applications simpler.

Our eventual goals on top of https://tiny.cc/istio-oidc-policy would also look to tie in with logic similar to this based on standard use cases we shared as part of http://tiny.cc/istio-iam-usecases.

1 Like
#7

This indeed is a good use case. We will look into supporting this.

#8

This rule worked for me. I am not sure about the handler section but I was able to add headers from the JWT payload this way.

apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: auth-headers
  namespace: istio-system
spec:
  match: source.labels["istio"] == "ingressgateway"
  actions:
  - handler: keyval.istio-system
    instances: [ keyval ]
  request_header_operations:
  - name: X-company-userId
    values:
    - request.auth.claims["sub"]
2 Likes
#9

request_header_operations and response_header_operations can already resolve static values in the values clause without any handler… if they could also directly reference attributes, it would solve this an other use cases.

1 Like