docs icon indicating copy to clipboard operation
docs copied to clipboard

Doc request: Describe User Authentication with Istio for the Knative broker

Open matzew opened this issue 3 years ago • 1 comments

Document how to protect a Knative Broker with JSON Web Token (JWT) and Istio, using the AuthorizationPolicy and RequestAuthentication types from istio

matzew avatar Mar 15 '22 16:03 matzew

Below is a suggested content. But I am not sure where exactly to place this? Admin vs Dev ? or mix?


User Authentication with Istio and JWT

This guide shows how to protect a Knative Broker with JSON Web Token (JWT) and Istio.

Before you begin

You need:

  • knative eventing
  • https://knative.dev/docs/install/installing-istio/

Prepare the broker

In order have Istio being able to handle JWT-based user authentication the knative-eventing namespace needs to be labeld:

kubectl label namespace knative-eventing istio-injection=enabled

And the pod for the broker-ingress needs to be restarted, so it does get the istio-proxy container injected as the sidecar:

kubectl delete pod mt-broker-ingress-57db965447-jkl2k -n knative-eventing 

We now see that the pod has two containers:

knative-eventing     mt-broker-ingress-57db965447-jxzfk           2/2     Running   1              175m

Create a Broker

Create a broker, like:

apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  namespace: default
  name: my-broker

get the URL from the broker:

kubectl get broker -A 
NAMESPACE   NAME        URL                                                                          AGE   READY   REASON
default     my-broker   http://broker-ingress.knative-eventing.svc.cluster.local/default/my-broker   6s    True    

Start a curl pod:

kubectl -n default run curl --image=radial/busyboxplus:curl -i --tty

Send a CloudEvent with an HTTP Post against the broker URL

curl -X POST -v \
    -H "content-type: application/json"  \
    -H "ce-specversion: 1.0"  \
    -H "ce-source: my/curl/command"  \
    -H "ce-type: my.demo.event"  \
    -H "ce-id: 0815"  \
    -d '{"value":"Hello Knative"}' \
    http://broker-ingress.knative-eventing.svc.cluster.local/default/my-broker

You will receive a 202 HTTP response code, that the broker did accept the request:

...
* Mark bundle as not supporting multiuse
< HTTP/1.1 202 Accepted
< allow: POST, OPTIONS
< date: Tue, 15 Mar 2022 13:37:57 GMT
< content-length: 0
< x-envoy-upstream-service-time: 79
< server: istio-envoy
< x-envoy-decorator-operation: broker-ingress.knative-eventing.svc.cluster.local:80/*

Protect the Broker

Now we apply a AuthorizationPolicy in the knative-eventing namespace to describe that the path to the my-broker object is restricted to a given user:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-jwt
  namespace: knative-eventing
spec:
  action: ALLOW
  rules:
  - from:
    - source:
       requestPrincipals: ["[email protected]/[email protected]"]
    to:
    - operation:
        methods: ["POST"]
        paths: ["/default/my-broker"]

For the user (requestPrincipal), we create a RequestAuthentication in the istio-system namespace which leverages some example JWT from Istio:

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: "jwt-example"
  namespace: istio-system
spec:
  jwtRules:
  - issuer: "[email protected]"
    jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.13/security/tools/jwt/samples/jwks.json"

Now retrying the curl example from above will result in a 403 - Forbidden response code from the server:

...
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< content-length: 19
< content-type: text/plain
< date: Tue, 15 Mar 2022 13:47:53 GMT
< server: istio-envoy
< connection: close
< x-envoy-decorator-operation: broker-ingress.knative-eventing.svc.cluster.local:80/*

Using the JWT to access the broker

In order to access the broker, we need to add the Bearer JSON Web Token as part of the request:

TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.13/security/tools/jwt/samples/demo.jwt -s)

curl -X POST -v \
    -H "content-type: application/json"  \
    -H "Authorization: Bearer ${TOKEN}"  \
    -H "ce-specversion: 1.0"  \
    -H "ce-source: my/curl/command"  \
    -H "ce-type: my.demo.event"  \
    -H "ce-id: 0815"  \
    -d '{"value":"Hello Knative"}' \
    http://broker-ingress.knative-eventing.svc.cluster.local/default/my-broker

Afterwards the server does respond with a 202 response code, indicating that it has accepted the HTTP request.

* Mark bundle as not supporting multiuse
< HTTP/1.1 202 Accepted
< allow: POST, OPTIONS
< date: Tue, 15 Mar 2022 14:05:09 GMT
< content-length: 0
< x-envoy-upstream-service-time: 40
< server: istio-envoy
< x-envoy-decorator-operation: broker-ingress.knative-eventing.svc.cluster.local:80/*

matzew avatar Mar 15 '22 16:03 matzew

@matzew it depends on whether admin permissions are required for any of the steps included here? For now I will put it in the admin section.

abrennan89 avatar Oct 10 '22 18:10 abrennan89