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.
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.
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.
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.
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.
Thanks! This works really well for ‘sub’. We put some custom claims in our JWTs and would like to extract them in the same way and add them to headers. So far my tests have been unsuccessful. I’m doing something like the above, but replacing ‘values’ with:
request.auth.claims["abc"]
Keeping two headers, one for sub and one for abc in the rule, sub comes back fine, but abc does not. I’m wondering if the request.auth construction only pull in certain well-known JWT claims, or if vendor-specific claims get added in a different way?
Can anyone , post a sample code snippet to extract claims from jwt and pass it as a custom headers.
I am really struggling. The kind ‘Rule’ for istio is not working for me . Any help or lead will be much appreciated. @ademaria@rob
I don’t think you can do that out-of-the-box with the current CRDs in Istio.
What you could do is, use the outputPayloadToHeader field in the RequestAuthentication resource to pass the JWT to the header of your choice. For example:
Then, any upstream requests will have the “my-jwt-header” and you can parse it from there. If you want to make any authz decisions based on the claims from the JWT, you’d use the AuthorizationPolicy to do that. For example:
Claims are not something Istio directly handles. You can add more claims to your JWT wherever you are generating the token.
There doesn’t seem to be anything in the RequestAuthentication resource that would allow you to pull out specific claims and add them as headers. You could put the whole payload as a header with the outputPayloadToHeader.