I have JWT authentication setup on the istio-ingressgateway
layer so that public clients have to present a JWT for authentication before their request is proxied internally within the service mesh. I also want the incoming request to have to meet an OPA Policy in order for the request to be authorized. The request.auth.*
attributes aren’t being generated downstream from the ingressgateway because there isn’t a JWT authentication policy on services within the mesh. How can I get the request.auth.claims
attribute generated so that Mixer can use it without having an authentication policy on the service (productpage
in this case) that the authorization check should take place on?
Here are the configurations I have so far:
apiVersion: "config.istio.io/v1alpha2"
kind: opa
metadata:
name: opa-handler
namespace: istio-system
spec:
policy:
- |+
package mixerauthz
default allow = false
allow {
input.subject.user = "jwhitaker@solutionreach.com"
input.action.method = "GET"
}
checkMethod: "data.mixerauthz.allow"
failClose: true
---
apiVersion: "config.istio.io/v1alpha2"
kind: authorization
metadata:
name: authz-instance
namespace: istio-system
spec:
action:
method: request.method | ""
namespace: destination.namespace | "default"
path: request.path | "/"
properties:
version: destination.labels["version"] | ""
subject:
user: request.auth.claims["sub"] | ""
groups: request.auth.claims["groups"] | ""
properties:
iss: request.auth.claims["iss"] | ""
---
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
name: opa-rule
namespace: istio-system
spec:
match: match(destination.service.name, "productpage")
actions:
- handler: opa-handler.opa.istio-system
instances:
- authz-instance.authorization.istio-system
---
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "user-auth-example"
namespace: istio-system
spec:
targets:
- name: istio-ingressgateway
origins:
- jwt:
issuer: "<issuer>"
jwksUri: "<jwks-uri>"
principalBinding: USE_ORIGIN
---
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: default
spec:
peers:
- mtls: {}
---
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "default"
namespace: "default"
spec:
host: "*.default.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
The use case I am trying to satisfy is this…
I would like to express an authentication policy where every service->service call within the service mesh occurs over mutual TLS, but clients outside the kubernetes cluster should present JWT authentication at the istio-ingressgateway
layer. The idea here is that we should be able to trust service calls within the service mesh, but public clients outside of the kubernetes cluster need to be authorized against an authorization system in our companies cloud. We may want to enforce RBAC authorization between services within the service mesh at a later time, but for now we just want public client calls into the service mesh to require JWT authentication, but calls between services within the mesh to use mTLS.