diff --git a/docs/latest/dev/README.md b/docs/latest/dev/README.md index 2c4e65356fa..0c3b055b619 100644 --- a/docs/latest/dev/README.md +++ b/docs/latest/dev/README.md @@ -126,6 +126,14 @@ Now you are able to view the running Envoy configuration by navigating to `127.0 There are many other endpoints on the [Envoy admin interface][] that may be helpful when debugging. +### JWT Testing + +An example [JSON Web Token (JWT)][jwt] and [JSON Web Key Set (JWKS)][jwks] are used for the [request authentication][] +user guide. The JWT was created by the [JWT Debugger][], using the `RS256` algorithm. The public key from the JWTs +verify signature was copied to [JWK Creator][] for generating the JWK. The JWK Creator was configured with matching +settings, i.e. `Signing` public key use and the `RS256` algorithm. The generated JWK was wrapped in a JWKS structure +and is hosted in the repo. + [Quickstart]: https://github.com/envoyproxy/gateway/blob/main/docs/user/quickstart.md [make]: https://www.gnu.org/software/make/ [Github Actions]: https://docs.github.com/en/actions @@ -137,3 +145,8 @@ There are many other endpoints on the [Envoy admin interface][] that may be help [gateway-dev]: https://hub.docker.com/r/envoyproxy/gateway-dev/tags [mac_connect]: https://github.com/chipmk/docker-mac-net-connect [Envoy admin interface]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface +[jwt]: https://tools.ietf.org/html/rfc7519 +[jwks]: https://tools.ietf.org/html/rfc7517 +[request authentication]: https://gateway.envoyproxy.io/latest/user/authn.html +[JWT Debugger]: https://jwt.io/ +[JWK Creator]: https://russelldavies.github.io/jwk-creator/ diff --git a/docs/latest/user/authn.md b/docs/latest/user/authn.md new file mode 100644 index 00000000000..ed86ad46c2c --- /dev/null +++ b/docs/latest/user/authn.md @@ -0,0 +1,94 @@ +# Request Authentication + +This guide provides instructions for configuring [JSON Web Token (JWT)][jwt] authentication. JWT authentication checks +if an incoming request has a valid JWT before routing the request to a backend service. Currently, Envoy Gateway only +supports validating a JWT from an HTTP header, e.g. `Authorization: Bearer `. + +## Installation + +Follow the steps from the [Quickstart](quickstart.md) guide to install Envoy Gateway and the example manifest. +Before proceeding, you should be able to query the example backend using HTTP. + +## Configuration + +Allow requests with a valid JWT by creating an [AuthenticationFilter][] and referencing it from the example HTTPRoute. + +```shell +kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/authn/jwt.yaml +``` + +The HTTPRoute is now updated to authenticate requests for `/foo` and allow unauthenticated requests to `/bar`. The +`/foo` route rule references an AuthenticationFilter that provides the JWT authentication configuration. + +Verify the HTTPRoute configuration and status: + +```shell +kubectl get httproute/backend -o yaml +``` + +The AuthenticationFilter is configured for JWT authentication and uses a single [JSON Web Key Set (JWKS)][jwks] +provider for authenticating the JWT. + +Verify the AuthenticationFilter configuration: + +```shell +kubectl get authenticationfilter/jwt-example -o yaml +``` + +## Testing + +Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](quickstart.md) guide is set. If not, follow the +Quickstart instructions to set the variable. + +```shell +echo $GATEWAY_HOST +``` + +Verify that requests to `/foo` are denied without a JWT: + +```shell +curl -sS -o /dev/null -H "Host: www.example.com" -w "%{http_code}\n" http://$GATEWAY_HOST/foo +``` + +A `401` HTTP response code should be returned. + +Get the JWT used for testing request authentication: + +```shell +TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode - +``` + +__Note:__ The above command decodes and returns the token's payload. You can replace `f2` with `f1` to view the token's +header. + +Verify that a request to `/foo` with a valid JWT is allowed: + +```shell +curl -sS -o /dev/null -H "Host: www.example.com" -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n" http://$GATEWAY_HOST/foo +``` + +A `200` HTTP response code should be returned. + +Verify that requests to `/bar` are allowed __without__ a JWT: + +```shell +curl -sS -o /dev/null -H "Host: www.example.com" -w "%{http_code}\n" http://$GATEWAY_HOST/bar +``` + +## Clean-Up + +Follow the steps from the [Quickstart](quickstart.md) guide to uninstall Envoy Gateway and the example manifest. + +Delete the AuthenticationFilter: + +```shell +kubectl delete authenticationfilter/jwt-example +``` + +## Next Steps + +Checkout the [Developer Guide](../dev/README.md) to get involved in the project. + +[jwt]: https://tools.ietf.org/html/rfc7519 +[AuthenticationFilter]: https://github.com/envoyproxy/gateway/blob/main/api/v1alpha1/authenticationfilter_types.go +[jwks]: https://tools.ietf.org/html/rfc7517 diff --git a/docs/latest/user_docs.rst b/docs/latest/user_docs.rst index 23a801d6833..3076de73518 100644 --- a/docs/latest/user_docs.rst +++ b/docs/latest/user_docs.rst @@ -18,3 +18,4 @@ Learn how to deploy, use, and operate Envoy Gateway. user/tcp-routing user/udp-routing user/grpc-routing + user/authn diff --git a/examples/kubernetes/authn/jwks.json b/examples/kubernetes/authn/jwks.json new file mode 100644 index 00000000000..6cd882726be --- /dev/null +++ b/examples/kubernetes/authn/jwks.json @@ -0,0 +1 @@ +{"keys":[{"kty":"RSA","n":"u1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0_IzW7yWR7QkrmBL7jTKEn5u-qKhbwKfBstIs-bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW_VDL5AaWTg0nLVkjRo9z-40RQzuVaE8AkAFmxZzow3x-VJYKdjykkJ0iT9wCS0DRTXu269V264Vf_3jvredZiKRkgwlL9xNAwxXFg0x_XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC-9aGVd-Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmw","e":"AQAB","alg":"RS256","use":"sig"}]} diff --git a/examples/kubernetes/authn/jwt.yaml b/examples/kubernetes/authn/jwt.yaml new file mode 100644 index 00000000000..db113716a96 --- /dev/null +++ b/examples/kubernetes/authn/jwt.yaml @@ -0,0 +1,47 @@ +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: AuthenticationFilter +metadata: + name: jwt-example +spec: + type: JWT + jwtProviders: + - name: example + remoteJWKS: + uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/authn/jwks.json +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: backend +spec: + parentRefs: + - name: eg + hostnames: + - "www.example.com" + rules: + - backendRefs: + - group: "" + kind: Service + name: backend + port: 3000 + weight: 1 + filters: + - extensionRef: + group: gateway.envoyproxy.io + kind: AuthenticationFilter + name: jwt-example + type: ExtensionRef + matches: + - path: + type: PathPrefix + value: /foo + - backendRefs: + - group: "" + kind: Service + name: backend + port: 3000 + weight: 1 + matches: + - path: + type: PathPrefix + value: /bar diff --git a/examples/kubernetes/authn/test.jwt b/examples/kubernetes/authn/test.jwt new file mode 100644 index 00000000000..1c9d949adf0 --- /dev/null +++ b/examples/kubernetes/authn/test.jwt @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.NHVaYe26MbtOYhSKkoKYdFVomg4i8ZJd8_-RU8VNbftc4TSMb4bXP3l3YlNWACwyXPGffz5aXHc6lty1Y2t4SWRqGteragsVdZufDn5BlnJl9pdR_kdVFUsra2rWKEofkZeIC4yWytE58sMIihvo9H1ScmmVwBcQP6XETqYd0aSHp1gOa9RdUPDvoXQ5oqygTqVtxaDr6wUFKrKItgBMzWIdNZ6y7O9E0DhEPTbE9rfBo6KTFsHAZnMg4k68CDp2woYIaXbmYTWcvbzIuHO7_37GT79XdIwkm95QJ7hYC9RiwrV7mesbY4PAahERJawntho0my942XheVLmGwLMBkQ