Setting request headers with values from a JWT

“I am getting nil value in dynamicMetadata()”

Where are you getting this? when doing what?

In the envoy filter to decode the JWT. Inside the inline code, I need some value in the meta variable. But I am getting nill value. I am thinking requestauthentication is adding the jwt (outputPayloadToHeader) after the envoy filter??

local meta = request_handle:streamInfo():dynamicMetadata():get(“envoy.filters.http.jwt_authn”)

   inlineCode: |
              function envoy_on_request(request_handle)
                local meta = request_handle:streamInfo():dynamicMetadata():get("envoy.filters.http.jwt_authn")
                request_handle:logWarn("meta"..meta)     
              end

error envoy lua script log: [string “function envoy_on_request(request_handle)…”]:3: attempt to concatenate local ‘meta’ (a nil value)

do you have authorizatoinpoliicy that requires the JWT token?
i think thats what is adding the jwt_authn

Yes I do similar to this one:

apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
  name: "jwt-echoserver"
  namespace: foo
spec:
  selector:
    matchLabels:
      app: echoserver
  jwtRules:
  - issuer: "testing@secure.istio.io"
    jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.7/security/tools/jwt/samples/jwks.json"
    outputPayloadToHeader: x-jwt

[/quote]

It’s requestAuthentication.
Can you try to add AuthorizationPolicy?
Not sure but maybe it’s needed

AuthorizationPolicy at Gateway level or service level? I have it at service level but not at Gateway level.

I have it on the gateway level. So every request to the mesh will need jwt. Later I allow some other public ones

@chen @jbilliau-rcd Figured it out. I am using ISTIO 1.9.1. By using the below filter chain, it works.

     - applyTo: HTTP_FILTER
            match:
              context: SIDECAR_INBOUND
              listener:
                filterChain:
                  filter:
                    name: "envoy.filters.network.http_connection_manager"
                    subFilter:
                      name: "envoy.filters.http.router"
            patch:
              operation: INSERT_BEFORE

So that looks identical to mine except you have “envoy.filters.network.http_connection_manager” where I have “envoy.http_connection_manager” for the filter name, and you have “envoy.filters.http.router” where I have “envoy.router” for the subfilter name…is that correct? Did my code work for you except those changes?

@jbilliau-rcd Yes, that is correct. I am guessing they might have changed the name of the filters in the new version. Also, I am running the envoy filter at the SIDECAR level and not at the GATEWAY level.

Correct, so am I…interesting, well, looks like you may have pro-actively helped me for when we migrate to Istio 1.9, i’ll keep this in mind!

Hi @Karmanjot_Singh what is your final soulution?

@aj_gdansk Final solution? The envoy filter was not working for me. I changed the filter and subfilter inside the filter chain to make it work.

Hi everyone, thanks for the discussions and all the workaround provided from the community.

The good news is we now have a proposal to support this in the RequestAuthentication API, please take a look and feel free to comment.

One thing we’re still discussing but would really appreciate if the community could provide feedback is about the headers to be set from the claims.

The current proposal allows to copy any claims to arbitrary headers as specified in the request authentication API, which is same as the the existing outputPayloadToHeader field.

I’m not sure if anyone would prefer to have any restrictions on the headers for any reasons? For example, only allow a list of predefined headers (e.g. x-istio-jwt-claim-sub, x-istio-jwt-claim-iss, x-istio-jwt-claim-group, etc.) or if you think such restrictions would make the feature useless because you are already using the workaround to extract claims to some arbitrary headers?

Please let us know your thoughts, thanks.

3 Likes

I am using isto 1.11.1 in demo mode. I do it according to the suggested instructions and do not get the result. I see this difference (Note: the JWT filter is also added but omitted in the above example). Can you tell me how to add this filter? If there is a brief instruction on what needs to be done in order to be routed by the claims from the jwt token, I would be grateful. So many answers and none work out of the box.

1 Like

Did you have to use all three RequestAuthentication, Authorization policy and Envoyfilter?

It would be great if you can paste the final spec files. I also using ISTIO 1.9

I am a newbie to ISTIO and similar to vmasyagin having a hard time too figure out the policies. It would be great if someone can paste their spec files for reference.

From what I understand,

  1. Create a policy to extract payload from jwt token and insert it in a new request header. Is this done using Istio / JWTRule? Is there a sample I can use for reference? What is the kind of this policy?
  2. In my setup the jwt token is in a custom header named x-amzn-oidc-data. Is the extra config needed for this fromHeaders or jwtHeaders? Istio / JWTRule
  3. Write an envoyfilter to extract the payload from the new header, decode base64 (since the previous step only extracts it) to get the claims

cc @chen @Karmanjot_Singh

That’s great news, and something we are looking to actively do right now. We would love the ability to route traffic in our VirtualService by the client_id within the passed in JWT. I’m currently trying to write an EnvoyFilter to do it but if it was natively supported that would be so much easier.

Any update on the progress of that proposal and possible ETA?

I think this is a great proposal.

I am looking to implement ratelimit using some of the oidc claim and this would be a great help.