External authentication store JWT in cookie

Hello

I use Istio + Keycloack + oauth2-proxy for client auth(n/z). It works well using CUSTOM action. However I also need to setup direct access to api endpoint using only JWT validation: now I have the following config:

---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: myapp-redirect-keycloak
spec:
  selector:
    matchLabels:
      app: myapp
  action: CUSTOM
  provider:
    name: oauth2-proxy
  rules:
  - to:
    - operation:
        notPaths: ["/static/*","/api/*"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: myapp-require-jwt
spec:
  selector:
    matchLabels:
      app: myapp
  action: ALLOW
  rules:
  - from:
    - source:
        requestPrincipals: ["*"]
  - to:
    - operation:
        paths: ["/static/*"]

---
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: myapp-keycloak-staging
spec:
  selector:
    matchLabels:
      app: myapp
  jwtRules:
  - issuer: redacted
    jwksUri: redacted
    fromHeaders:
    - name: x-auth-request-access-token
---
...
    meshConfig:
      extensionProviders:
      - envoyExtAuthzHttp:
          headersToDownstreamOnDeny:
          - content-type
          - set-cookie
          headersToUpstreamOnAllow:
          - authorization
          - path
          - x-auth-request-user
          - x-auth-request-email
          - x-auth-request-access-token
          includeHeadersInCheck:
          - authorization
          - cookie
          port: "80"
          service: "keycloak-oauth2-proxy.istio-keycloak.svc.cluster.local"
        name: "oauth2-proxy"
...

Basically I want to disable redirect to auth page for /api path and use only jwt validation for that path. It works well, but some app’s functionality depends on user’s ability to contact /api endpoint from the browser (html page is being populated from /api requests from browser). Since all requests to /api endpoint don’t come to oauth2-proxy, x-auth-request-access-token header is not set automatically by it and web users get an error during page load.

From my understanding oauth2-proxy can’t store a cookie with plain jwt and RequestAuthentication can’t validate jwt from cookies, so using EnvoyFilter after successful auth I should store jwt in some arbitrary cookie and then extract it and put it into x-auth-request-access-token header for all requests to /api. Is it possible to do at all? Is this good approach or there’s a better one?

Thank you

Didn’t you disable the auth redirect for /api intentionally because you only want to do a simple JWT validation on it. This means your client (e.g. browser) should include the proper JWT in the request otherwise it will fail. What do you want the EnvoyFilter to do in this case if the request has no JWT at all?

Didn’t you disable the auth redirect for /api intentionally because you only want to do a simple JWT validation on it.

That’s correct. Basically we have 2 kinds of clients for our api endpoint: web users via browser (need redirect to auth-proxy) and services(only jwt validation and 401/3 if jwt is missing). The question is what we can do to achieve that with Istio?

What do you want the EnvoyFilter to do in this case if the request has no JWT at all?

For web clients, since they’re already authenticated and authorised it should be no-brainer to allow them to visit /api endpoint with some Envoyfilter magic, but maybe there is a better way for doing this?

Just to clarify, the web users via browser is already supported by your current CUSTOM authz policy and auth-proxy, and now you have services with JWT that you want to opt-out from the redirection to auth-proxy and still validate its JWT token?

If that’s the case, I think one way to do this is to update your CUSTOM authz policy to skip those requests that already has JWT, this could be achieved by checking the HTTP header that is used to pass the JWT token.