diff --git a/README.md b/README.md index cb6f37a65..b21b2eafe 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ instead it will opt to connect with what’s there and what’s being developed Kuadrant is a system of cloud-native k8s components that grows as users’ needs grow. -* From simple protection of a Service (via **AuthN**) that is used by teammates working on the same cluster, or “sibling” services, up to **AuthZ** of users using OIDC plus custom policies. -* From no rate-limiting to rate-limiting for global service protection on to rate-limiting by users/plans +- From simple protection of a Service (via **AuthN**) that is used by teammates working on the same cluster, or “sibling” services, up to **AuthZ** of users using OIDC plus custom policies. +- From no rate-limiting to rate-limiting for global service protection on to rate-limiting by users/plans ## Architecture @@ -35,7 +35,7 @@ to operate the cluster ingress gateway to provide API management with **authenti ### Kuadrant components | CRD | Description | -|----------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Control Plane | The control plane takes the customer desired configuration (declaratively as kubernetes custom resources) as input and ensures all components are configured to obey customer's desired behavior.
This repository contains the source code of the kuadrant control plane | | [Kuadrant Operator](https://github.com/Kuadrant/kuadrant-operator) | A Kubernetes Operator to manage the lifecycle of the kuadrant deployment | | [Authorino](https://github.com/Kuadrant/authorino) | The AuthN/AuthZ enforcer. As the [external istio authorizer](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/) ([envoy external authorization](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter) serving gRPC service) | @@ -48,19 +48,19 @@ to operate the cluster ingress gateway to provide API management with **authenti The kuadrant control plane owns the following [Custom Resource Definitions, CRDs](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/): -| CRD | Description | Example | -|-----------------------------------------------------------------------------------------------------|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------| -| AuthPolicy CRD [\[doc\]](doc/auth.md) [[reference]](doc/reference/authpolicy.md) | Enable AuthN and AuthZ based access control on workloads | [AuthPolicy CR](https://github.com/Kuadrant/kuadrant-operator/blob/main/examples/toystore/authpolicy.yaml) | -| RateLimitPolicy CRD [\[doc\]](doc/rate-limiting.md) [[reference]](doc/reference/ratelimitpolicy.md) | Enable access control on workloads based on HTTP rate limiting | [RateLimitPolicy CR](https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/main/examples/toystore/ratelimitpolicy_httproute.yaml) | -| DNSPolicy CRD [\[doc\]](doc/dns.md) [[reference]](doc/reference/dnspolicy.md) | Enable DNS management | [DNSPolicy CR](config/samples/kuadrant_v1_dnspolicy.yaml) | -| TLSPolicy CRD [\[doc\]](doc/tls.md) [[reference]](doc/reference/tlspolicy.md) | Enable TLS management | [TLSPolicy CR](config/samples/kuadrant_v1_tlspolicy.yaml) | +| CRD | Description | Example | +| ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| AuthPolicy CRD [\[doc\]](doc/overviews/auth.md) [[reference]](doc/reference/authpolicy.md) | Enable AuthN and AuthZ based access control on workloads | [AuthPolicy CR](https://github.com/Kuadrant/kuadrant-operator/blob/main/examples/toystore/authpolicy.yaml) | +| RateLimitPolicy CRD [\[doc\]](doc/overviews/rate-limiting.md) [[reference]](doc/reference/ratelimitpolicy.md) | Enable access control on workloads based on HTTP rate limiting | [RateLimitPolicy CR](https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/main/examples/toystore/ratelimitpolicy_httproute.yaml) | +| DNSPolicy CRD [\[doc\]](doc/overviews/dns.md) [[reference]](doc/reference/dnspolicy.md) | Enable DNS management | [DNSPolicy CR](config/samples/kuadrant_v1_dnspolicy.yaml) | +| TLSPolicy CRD [\[doc\]](doc/overviews/tls.md) [[reference]](doc/reference/tlspolicy.md) | Enable TLS management | [TLSPolicy CR](config/samples/kuadrant_v1_tlspolicy.yaml) | Additionally, Kuadrant provides the following CRDs -| CRD | Owner | Description | Example | -|--------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|-------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| -| [Kuadrant CRD](https://github.com/Kuadrant/kuadrant-operator/blob/main/api/v1beta1/kuadrant_types.go) | [Kuadrant Operator](https://github.com/Kuadrant/kuadrant-operator) | Represents an instance of kuadrant | [Kuadrant CR](https://github.com/Kuadrant/kuadrant-operator/blob/main/config/samples/kuadrant_v1beta1_kuadrant.yaml) | -| [Limitador CRD](https://github.com/Kuadrant/limitador-operator/blob/main/api/v1alpha1/limitador_types.go) | [Limitador Operator](https://github.com/Kuadrant/limitador-operator) | Represents an instance of Limitador | [Limitador CR](https://github.com/Kuadrant/limitador-operator/blob/main/config/samples/limitador_v1alpha1_limitador.yaml) | +| CRD | Owner | Description | Example | +| ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| [Kuadrant CRD](https://github.com/Kuadrant/kuadrant-operator/blob/main/api/v1beta1/kuadrant_types.go) | [Kuadrant Operator](https://github.com/Kuadrant/kuadrant-operator) | Represents an instance of kuadrant | [Kuadrant CR](https://github.com/Kuadrant/kuadrant-operator/blob/main/config/samples/kuadrant_v1beta1_kuadrant.yaml) | +| [Limitador CRD](https://github.com/Kuadrant/limitador-operator/blob/main/api/v1alpha1/limitador_types.go) | [Limitador Operator](https://github.com/Kuadrant/limitador-operator) | Represents an instance of Limitador | [Limitador CR](https://github.com/Kuadrant/limitador-operator/blob/main/config/samples/limitador_v1alpha1_limitador.yaml) | | [Authorino CRD](https://docs.kuadrant.io/latest/authorino-operator/#the-authorino-custom-resource-definition-crd) | [Authorino Operator](https://github.com/Kuadrant/authorino-operator) | Represents an instance of Authorino | [Authorino CR](https://github.com/Kuadrant/authorino-operator/blob/main/config/samples/authorino-operator_v1beta1_authorino.yaml) | Kuadrant Architecture @@ -69,17 +69,17 @@ Additionally, Kuadrant provides the following CRDs ### Pre-requisites -* Istio or Envoy Gateway is installed in the cluster. Otherwise, refer to the +- Istio or Envoy Gateway is installed in the cluster. Otherwise, refer to the [Istio getting started guide](https://istio.io/latest/docs/setup/getting-started/) or [EnvoyGateway getting started guide](https://gateway.envoyproxy.io/docs/). -* Kubernetes Gateway API is installed in the cluster. -* cert-manager is installed in the cluster. Otherwise, refer to the +- Kubernetes Gateway API is installed in the cluster. +- cert-manager is installed in the cluster. Otherwise, refer to the [cert-manager installation guide](https://cert-manager.io/docs/installation/). ### Installing Kuadrant Installing Kuadrant is a two-step procedure. Firstly, install the Kuadrant Operator and secondly, -request a Kuadrant instance by creating a *Kuadrant* custom resource. +request a Kuadrant instance by creating a _Kuadrant_ custom resource. #### 1. Install the Kuadrant Operator @@ -130,33 +130,33 @@ EOF ### Protect your service -#### If you are an *API Provider* +#### If you are an _API Provider_ -* Deploy the service/API to be protected ("Upstream") -* Expose the service/API using the kubernetes Gateway API, ie +- Deploy the service/API to be protected ("Upstream") +- Expose the service/API using the kubernetes Gateway API, ie [HTTPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute) object. -* Write and apply the Kuadrant's [RateLimitPolicy](doc/rate-limiting.md) and/or - [AuthPolicy](doc/auth.md) custom resources targeting the HTTPRoute resource +- Write and apply the Kuadrant's [RateLimitPolicy](doc/overviews/rate-limiting.md) and/or + [AuthPolicy](doc/overviews/auth.md) custom resources targeting the HTTPRoute resource to have your API protected. -#### If you are a *Cluster Operator* +#### If you are a _Cluster Operator_ -* (Optionally) deploy ingress gateway using the +- (Optionally) deploy ingress gateway using the [Gateway](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway) resource. -* Write and apply the Kuadrant's [RateLimitPolicy](doc/rate-limiting.md) and/or - [AuthPolicy](doc/auth.md) custom resources targeting the Gateway resource +- Write and apply the Kuadrant's [RateLimitPolicy](doc/overviews/rate-limiting.md) and/or + [AuthPolicy](doc/overviews/auth.md) custom resources targeting the Gateway resource to have your gateway traffic protected. ## User guides The user guides section of the docs gathers several use-cases as well as the instructions to implement them using kuadrant. -* [Simple Rate Limiting for Application Developers](doc/user-guides/simple-rl-for-app-developers.md) -* [Authenticated Rate Limiting for Application Developers](doc/user-guides/authenticated-rl-for-app-developers.md) -* [Gateway Rate Limiting for Cluster Operators](doc/user-guides/gateway-rl-for-cluster-operators.md) -* [Authenticated Rate Limiting with JWTs and Kubernetes RBAC](doc/user-guides/authenticated-rl-with-jwt-and-k8s-authnz.md) +- [Simple Rate Limiting for Application Developers](doc/user-guides/ratelimiting/simple-rl-for-app-developers.md) +- [Authenticated Rate Limiting for Application Developers](doc/user-guides/ratelimiting/authenticated-rl-for-app-developers.md) +- [Gateway Rate Limiting for Cluster Operators](doc/user-guides/ratelimiting/gateway-rl-for-cluster-operators.md) +- [Authenticated Rate Limiting with JWTs and Kubernetes RBAC](doc/user-guides/ratelimiting/authenticated-rl-with-jwt-and-k8s-authnz.md) -## [Kuadrant Rate Limiting](doc/rate-limiting.md) +## [Kuadrant Rate Limiting](doc/overviews/rate-limiting.md) ## Documentation @@ -164,7 +164,7 @@ Docs can be found on the [Kuadrant website](https://kuadrant.io/). ## Contributing -The [Development guide](doc/development.md) describes how to build the kuadrant operator and +The [Development guide](doc/overviews/development.md) describes how to build the kuadrant operator and how to test your changes before submitting a patch or opening a PR. Join us on the [#kuadrant](https://kubernetes.slack.com/archives/C05J0D0V525) channel in the Kubernetes Slack workspace, @@ -176,5 +176,4 @@ This software is licensed under the [Apache 2.0 license](https://www.apache.org/ See the LICENSE and NOTICE files that should have been provided along with this software for details. - [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FKuadrant%2Fkuadrant-operator.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FKuadrant%2Fkuadrant-operator?ref=badge_large) diff --git a/config/install/README.md b/config/install/README.md index d9c7a5d85..343431719 100644 --- a/config/install/README.md +++ b/config/install/README.md @@ -10,7 +10,7 @@ - Accessible Redis instance, for persistent storage for your rate limit counters. (Optional) -> Note: By default the following guide will install the "latest" or "main" version of Kuadrant. To pick a specific version, change the image in the `config/deploy/install/standard/kustomization.yaml`. All versions available can be found on the Kuadrant operator [release page](https://github.com/Kuadrant/kuadrant-operator/releases) +> Note: By default the following guide will install the "latest" or "main" version of Kuadrant. To pick a specific version, change the image in the `config/install/standard/kuadrant-version.yaml`. All versions available can be found on the Kuadrant operator [release page](https://github.com/Kuadrant/kuadrant-operator/releases) > Note: for multiple clusters, it would make sense to do the installation via a tool like [argocd](https://argo-cd.readthedocs.io/en/stable/). For other methods of addressing multiple clusters take a look at the [kubectl docs](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) @@ -19,19 +19,19 @@ > Note this uses the community operatorhub catalog. If you are installing on OpenShift and want to use the redhat provided catalog use the second command. -``` +```bash # community catalog kubectl apply -k config/install/standard ``` -``` +```bash # redhat catalog kubectl apply -k config/install/openshift ``` Verify both Kuadrant and sail operators are installed. Note, that this can take a while. You can also take a look at the subscription and installplan resource to help with debugging but the end state should be as below: -``` +```bash kubectl get deployments -n kuadrant-system @@ -45,7 +45,7 @@ kubectl get deployments -n kuadrant-system -``` +```bash kubectl get deployments -n gateway-system @@ -71,7 +71,7 @@ This will configure Kuadrant and Sail to install their components, set the crede Validate Kuadrant is ready via the kuadrant resource status condition -``` +```bash kubectl get kuadrant kuadrant -n kuadrant-system -o=yaml ``` @@ -81,7 +81,7 @@ At this point Kuadrant is ready to use. Below are some additional configuration create a `redis-credential.env` in the `config/install/configure/redis-storage` dir -``` +```bash kubectl apply -k config/install/configure/redis-storage ``` @@ -91,7 +91,7 @@ This will setup limitador to use provided redis connection URL as a backend stor Validate Kuadrant is in a ready state as before: -``` +```bash kubectl get kuadrant kuadrant -n kuadrant-system -o=yaml ``` diff --git a/config/install/standard/kuadrant-version.yaml b/config/install/standard/kuadrant-version.yaml index 135d7016a..8eba0cb4b 100644 --- a/config/install/standard/kuadrant-version.yaml +++ b/config/install/standard/kuadrant-version.yaml @@ -3,4 +3,4 @@ kind: CatalogSource metadata: name: kuadrant-operator-catalog spec: - image: quay.io/kuadrant/kuadrant-operator-catalog:v1.0.0-rc6 #change this to the version you want to install + image: quay.io/kuadrant/kuadrant-operator-catalog:latest #change this to the version you want to install diff --git a/doc/install/install-kubernetes.md b/doc/install/install-kubernetes.md index 1df642d39..da3246686 100644 --- a/doc/install/install-kubernetes.md +++ b/doc/install/install-kubernetes.md @@ -1,7 +1,6 @@ # Install Kuadrant on a Kubernetes cluster !!! note - You must perform these steps on each Kubernetes cluster where you want to use Kuadrant. !!! warning @@ -31,7 +30,6 @@ kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/downloa ### Install [OLM](https://olm.operatorframework.io/) !!! note - Currently, we recommend installing our operator via OLM. We plan to support Helm soon. ```bash @@ -41,12 +39,10 @@ curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releas ### (Optional) Install Istio as a Gateway API provider !!! note - Skip this step if planing to use [Envoy Gateway](https://gateway.envoyproxy.io/) as Gateway API provider -!!! note - There are several ways to install Istio (via `istioctl`, Helm chart or Operator) - this is just an example for starting from a bare Kubernetes cluster. +There are several ways to install Istio (via `istioctl`, Helm chart or Operator) - this is just an example for starting from a bare Kubernetes cluster. ```bash curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.5 sh - @@ -58,12 +54,9 @@ kubectl apply -f https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/ma ### (Optional) Install Envoy Gateway as a Gateway API provider !!! note - Skip this step if planing to use [Istio](https://istio.io/) as Gateway API provider -!!! note - - There are several ways to install Envoy Gateway (via `egctl`, Helm chart or Kubernetes yaml) - this is just an example for starting from a bare Kubernetes cluster. +There are several ways to install Envoy Gateway (via `egctl`, Helm chart or Kubernetes yaml) - this is just an example for starting from a bare Kubernetes cluster. ```bash helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system --create-namespace @@ -213,4 +206,4 @@ If you are using a local kind cluster, we recommend using [metallb](https://meta ## Next Steps -- [Secure, protect, and connect APIs with Kuadrant on Kubernetes](../user-guides/secure-protect-connect.md) +- [Secure, protect, and connect APIs with Kuadrant on Kubernetes](../user-guides/full-walkthrough/secure-protect-connect-k8s.md) diff --git a/doc/install/install-make.md b/doc/install/install-make.md new file mode 100644 index 000000000..c0e6153bb --- /dev/null +++ b/doc/install/install-make.md @@ -0,0 +1,37 @@ +# Installing Kuadrant via make targets + +## Overview +The following doc will show you how to install the Kuadrant Operator using make targets in the Kuadrant operator repo. What will be installed is Istio, Kubernetes Gateway API and Kuadrant itself. + +For other methods of installation see +- [k8s](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-kubernetes.md) +- [Openshift](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-openshift.md) + +> **Note:** In production environment, these steps are usually performed by a cluster operator with administrator privileges over the Kubernetes cluster. + +### Pre-requisites +- [Kind](https://kind.sigs.k8s.io) +- [Docker](https://docker.io) or [Podman](https://podman.io/) + +### Setup + +Clone the project: +```sh +git clone https://github.com/Kuadrant/kuadrant-operator && cd kuadrant-operator +``` + +Setup the environment (This will also create a kind cluster. If your using Pod man use the env var CONTAINER_ENGINE=podman with the make target below.): +```sh +make local-setup +``` + +Request an instance of Kuadrant: +```sh +kubectl -n kuadrant-system apply -f - <**Note:** Before using Kuadrant's `TLSPolicy` you will need to setup a certificate issuer refer to the [cert-manager docs for more details](https://cert-manager.io/docs/configuration/acme/dns01/route53/#creating-an-issuer-or-clusterissuer) - +> **Note:** Before using Kuadrant's `TLSPolicy` you will need to setup a certificate issuer refer to the [cert-manager docs for more details](https://cert-manager.io/docs/configuration/acme/dns01/route53/#creating-an-issuer-or-clusterissuer) ### Step 4 - (Optional) Install and configure Istio with the Sail Operator @@ -134,11 +132,11 @@ spec: version: v1.23.0 values: pilot: - autoscaleEnabled: false + autoscaleEnabled: false EOF ``` -More details on what can be configured can be found by executing +More details on what can be configured can be found by executing ``` kubectl explain istio.spec.values @@ -223,7 +221,7 @@ kubectl apply -f https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/re There is 1 more metrics configuration that needs to be applied so that all relevant metrics are being scraped. That configuration depends on where you deploy your Gateway later. - The steps to configure that are detailed in the follow on [Secure, protect, and connect](../user-guides/secure-protect-connect-single-multi-cluster.md) guide. + The steps to configure that are detailed in the follow on [Secure, protect, and connect](../user-guides/full-walkthrough/secure-protect-connect-openshift.md) guide. The [example Grafana dashboards and alerts](https://docs.kuadrant.io/latest/kuadrant-operator/doc/observability/examples/) for observing Kuadrant functionality use low-level CPU metrics and network metrics available from the user monitoring stack in OpenShift. They also use resource state metrics from Gateway API and Kuadrant resources. @@ -263,7 +261,6 @@ spec: EOF ``` - ### Step 8 - Install the Kuadrant Operator To install the Kuadrant Operator, enter the following command: @@ -300,7 +297,6 @@ kubectl get installplan -n kuadrant-system -o=jsonpath='{.items[0].status.phase} After some time, this command should return `complete`. - #### Set up a DNSProvider The example here is for AWS Route 53. It is important the secret for the DNSProvider is setup in the same namespace as the gateway. @@ -320,12 +316,9 @@ kubectl -n ingress-gateway create secret generic aws-credentials \ For more details on other providers take a look at [DNS Providers](https://docs.kuadrant.io/latest/dns-operator/docs/provider/) - #### Setup TLS DNS verification credential -When setting up TLS certs via provider like lets-encrypt, cert-manager will do a DNS based verification. To allow it do this, it will need a similar credential to that one set up for the DNSProvider, but it needs to be created in the cert-manager namespace where the operator is installed. - - +When setting up TLS certs via provider like lets-encrypt, cert-manager will do a DNS based verification. To allow it do this, it will need a similar credential to that one set up for the DNSProvider, but it needs to be created in the cert-manager namespace where the operator is installed. ```bash kubectl -n cert-manager create secret generic aws-credentials \ @@ -345,7 +338,7 @@ kind: Kuadrant metadata: name: kuadrant namespace: kuadrant-system - + EOF ``` @@ -363,8 +356,6 @@ This will setup and configure a number of Kuadrant subcomponents. Some of these - Learn More:(Limitador CRD)[https://docs.kuadrant.io/latest/limitador-operator/#features] - DNS Operator (Enforcement Component for DNSPOlicy) - - ### Configuring Redis Storage for Limitador #### Redis credentials for storage of rate limiting counters @@ -400,7 +391,6 @@ kubectl wait limitador/limitador -n kuadrant-system --for="condition=Ready=true" Kuadrant is now ready to use. - ### Step 10 - Configure the Kuadrant Console Plugin When running on OpenShift, the Kuadrant Operator will automatically install and configure the Kuadrant dynamic console plugin. @@ -422,4 +412,4 @@ Once the plugin is loaded, refresh the console. You should see a new **Kuadrant* ## Next steps -- [Secure, protect, and connect APIs with Kuadrant on OpenShift](../user-guides/secure-protect-connect-single-multi-cluster.md) +- [Secure, protect, and connect APIs with Kuadrant on OpenShift](../user-guides/full-walkthrough/secure-protect-connect-openshift.md) diff --git a/doc/auth.md b/doc/overviews/auth.md similarity index 89% rename from doc/auth.md rename to doc/overviews/auth.md index 899fd4e2f..df48c1779 100644 --- a/doc/auth.md +++ b/doc/overviews/auth.md @@ -12,6 +12,7 @@ A Kuadrant AuthPolicy custom resource: ### Envoy's External Authorization Protocol Kuadrant's Auth implementation relies on the Envoy's [External Authorization](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter) protocol. The workflow per request goes: + 1. On incoming request, the gateway checks the matching rules for enforcing the auth rules, as stated in the AuthPolicy custom resources and targeted Gateway API networking objects 2. If the request matches, the gateway sends one [CheckRequest](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto#envoy-v3-api-msg-service-auth-v3-checkrequest) to the external auth service ("Authorino"). 3. The external auth service responds with a [CheckResponse](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto#service-auth-v3-checkresponse) back to the gateway with either an `OK` or `DENIED` response code. @@ -24,18 +25,18 @@ An AuthPolicy and its targeted Gateway API networking resource contain all the s The `AuthPolicy` spec includes the following parts: -* A reference to an existing Gateway API resource (`spec.targetRef`) -* Authentication/authorization scheme (`spec.rules`) -* Top-level additional conditions (`spec.when`) -* List of named patterns (`spec.patterns`) +- A reference to an existing Gateway API resource (`spec.targetRef`) +- Authentication/authorization scheme (`spec.rules`) +- Top-level additional conditions (`spec.when`) +- List of named patterns (`spec.patterns`) The auth scheme specify rules for: -* Authentication (`spec.rules.authentication`) -* External auth metadata fetching (`spec.rules.metadata`) -* Authorization (`spec.rules.authorization`) -* Custom response items (`spec.rules.response`) -* Callbacks (`spec.rules.callbacks`) +- Authentication (`spec.rules.authentication`) +- External auth metadata fetching (`spec.rules.metadata`) +- Authorization (`spec.rules.authorization`) +- Custom response items (`spec.rules.response`) +- Callbacks (`spec.rules.callbacks`) Each auth rule can declare specific `when` conditions for the rule to apply. @@ -67,7 +68,7 @@ spec: # Sets of common patterns of selector-operator-value triples, to be referred by name in `when` conditions # and pattern-matching rules. Often employed to avoid repetition in the policy. # Equivalent to if otherwise declared within `defaults`. - patterns: {…} + patterns: { … } # The auth rules to apply to the network traffic routed through the targeted resource. # Equivalent to if otherwise declared within `defaults`. @@ -79,7 +80,7 @@ spec: "my-authn-rule": # The authentication method of this rule. # One-of: apiKey, jwt, oauth2Introspection, kubernetesTokenReview, x509, plain, anonymous. - apiKey: {…} + apiKey: { … } # Where credentials are required to be passed in the request for authentication based on this rule. # One-of: authorizationHeader, customHeader, queryString, cookie. @@ -91,14 +92,14 @@ spec: when: […] # Configs for caching the resolved object returned out of evaluating this auth rule. - cache: {…} + cache: { … } # Rules for fetching auth metadata from external sources. metadata: "my-external-source": # The method for fetching metadata from the external source. # One-of: http: userInfo, uma. - http: {…} + http: { … } # Authorization rules to enforce. # All policies must allow access for the auth request be successful. @@ -106,15 +107,15 @@ spec: "my-authz-rule": # The authorization method of this rule. # One-of: patternMatching, opa, kubernetesSubjectAccessReview, spicedb. - opa: {…} + opa: { … } # Customizations to the authorization response. response: # Custom denial status and other HTTP attributes for unauthenticated requests. - unauthenticated: {…} + unauthenticated: { … } # Custom denial status and other HTTP attributes for unauhtorized requests. - unauthorized: {…} + unauthorized: { … } # Custom response items when access is granted. success: @@ -122,19 +123,19 @@ spec: headers: "my-custom-header": # One-of: plain, json, wristband. - plain: {…} + plain: { … } # Custom response items wrapped as envoy dynamic metadata. dynamicMetadata: # One-of: plain, json, wristband. "my-custom-dyn-metadata": - json: {…} + json: { … } # Rules for post-authorization callback requests to external services. # Triggered regardless of the result of the authorization request. callbacks: "my-webhook": - http: {…} + http: { … } # Explicit defaults. Used in policies that target a Gateway object to express default rules to be enforced on # routes that lack a more specific policy attached to. @@ -142,13 +143,13 @@ spec: # the spec. defaults: rules: - authentication: {…} - metadata: {…} - authorization: {…} - response: {…} - callbacks: {…} + authentication: { … } + metadata: { … } + authorization: { … } + response: { … } + callbacks: { … } when: […] - patterns: {…} + patterns: { … } # Overrides. Used in policies that target a Gateway object to be enforced on all routes linked to the gateway, # thus also overriding any more specific policy occasionally attached to any of those routes. @@ -156,16 +157,16 @@ spec: # the spec. overrides: rules: - authentication: {…} - metadata: {…} - authorization: {…} - response: {…} - callbacks: {…} + authentication: { … } + metadata: { … } + authorization: { … } + response: { … } + callbacks: { … } when: […] - patterns: {…} + patterns: { … } ``` -Check out the [API reference](reference/authpolicy.md) for a full specification of the AuthPolicy CRD. +Check out the [API reference](../reference/authpolicy.md) for a full specification of the AuthPolicy CRD. ## Using the AuthPolicy @@ -187,7 +188,7 @@ spec: group: gateway.networking.k8s.io kind: HTTPRoute name: - rules: {…} + rules: { … } ``` ``` @@ -216,11 +217,13 @@ If an AuthPolicy targets a route defined for `*.com` and another AuthPolicy targ E.g., a request coming for `api.com` will be protected according to the rules from the AuthPolicy that targets the route for `api.com`; while a request for `other.com` will be protected with the rules from the AuthPolicy targeting the route for `*.com`. Example with 3 AuthPolicies and 3 HTTPRoutes: + - AuthPolicy A → HTTPRoute A (`a.toystore.com`) - AuthPolicy B → HTTPRoute B (`b.toystore.com`) - AuthPolicy W → HTTPRoute W (`*.toystore.com`) Expected behavior: + - Request to `a.toystore.com` → AuthPolicy A will be enforced - Request to `b.toystore.com` → AuthPolicy B will be enforced - Request to `other.toystore.com` → AuthPolicy W will be enforced @@ -248,7 +251,7 @@ spec: kind: Gateway name: defaults: # alternatively: `overrides` - rules: {…} + rules: { … } ``` ``` @@ -277,12 +280,14 @@ Two possible semantics are to be considered here – gateway policy _defaults_ v Gateway AuthPolicies that declare _defaults_ (or alternatively neither defaults nor overrides) protect all traffic routed through the gateway except where a more specific HTTPRoute AuthPolicy exists, in which case the HTTPRoute AuthPolicy prevails. Example with 4 AuthPolicies, 3 HTTPRoutes and 1 Gateway _default_ (plus 2 HTTPRoute and 2 Gateways without AuthPolicies attached): + - AuthPolicy A → HTTPRoute A (`a.toystore.com`) → Gateway G (`*.com`) - AuthPolicy B → HTTPRoute B (`b.toystore.com`) → Gateway G (`*.com`) - AuthPolicy W → HTTPRoute W (`*.toystore.com`) → Gateway G (`*.com`) - AuthPolicy G (defaults) → Gateway G (`*.com`) Expected behavior: + - Request to `a.toystore.com` → AuthPolicy A will be enforced - Request to `b.toystore.com` → AuthPolicy B will be enforced - Request to `other.toystore.com` → AuthPolicy W will be enforced @@ -292,12 +297,14 @@ Expected behavior: Gateway AuthPolicies that declare _overrides_ protect all traffic routed through the gateway, regardless of existence of any more specific HTTPRoute AuthPolicy. Example with 4 AuthPolicies, 3 HTTPRoutes and 1 Gateway _override_ (plus 2 HTTPRoute and 2 Gateways without AuthPolicies attached): + - AuthPolicy A → HTTPRoute A (`a.toystore.com`) → Gateway G (`*.com`) - AuthPolicy B → HTTPRoute B (`b.toystore.com`) → Gateway G (`*.com`) - AuthPolicy W → HTTPRoute W (`*.toystore.com`) → Gateway G (`*.com`) - AuthPolicy G (overrides) → Gateway G (`*.com`) Expected behavior: + - Request to `a.toystore.com` → AuthPolicy G will be enforced - Request to `b.toystore.com` → AuthPolicy G will be enforced - Request to `other.toystore.com` → AuthPolicy G will be enforced @@ -319,16 +326,17 @@ Authorino [JSON path string modifiers](https://docs.kuadrant.io/latest/authorino ### Examples Check out the following user guides for examples of protecting services with Kuadrant: -* [Enforcing authentication & authorization with Kuadrant AuthPolicy, for app developers and platform engineers](user-guides/auth-for-app-devs-and-platform-engineers.md) -* [Authenticated Rate Limiting for Application Developers](user-guides/authenticated-rl-for-app-developers.md) -* [Authenticated Rate Limiting with JWTs and Kubernetes RBAC](user-guides/authenticated-rl-with-jwt-and-k8s-authnz.md) + +- [Enforcing authentication & authorization with Kuadrant AuthPolicy, for app developers and platform engineers](../user-guides/auth/auth-for-app-devs-and-platform-engineers.md) +- [Authenticated Rate Limiting for Application Developers](../user-guides/ratelimiting/authenticated-rl-for-app-developers.md) +- [Authenticated Rate Limiting with JWTs and Kubernetes RBAC](../user-guides/ratelimiting/authenticated-rl-with-jwt-and-k8s-authnz.md) ### Known limitations -* One HTTPRoute can only be targeted by one AuthPolicy. -* One Gateway can only be targeted by one AuthPolicy. -* AuthPolicies can only target HTTPRoutes/Gateways defined within the same namespace of the AuthPolicy. -* 2+ AuthPolicies cannot target network resources that define/inherit the same exact hostname. +- One HTTPRoute can only be targeted by one AuthPolicy. +- One Gateway can only be targeted by one AuthPolicy. +- AuthPolicies can only target HTTPRoutes/Gateways defined within the same namespace of the AuthPolicy. +- 2+ AuthPolicies cannot target network resources that define/inherit the same exact hostname. #### Limitation: Multiple network resources with identical hostnames @@ -421,9 +429,10 @@ Authorino looks up for the auth scheme (`AuthConfig` custom resource) to enforce
Exception to the rule - Due to limitations imposed by the Istio `AuthorizationPolicy`, there are a few patterns of HTTPRouteRules that cannot be translated to filters for the external authorization request. Therefore, the following patterns used in HTTPRouteMatches of top-level route selectors of an AuthPolicy will not be included in the Istio AuthorizationPolicy rules that trigger the check request with Authorino: `PathMatchRegularExpression`, `HeaderMatchRegularExpression`, and `HTTPQueryParamMatch`. +Due to limitations imposed by the Istio `AuthorizationPolicy`, there are a few patterns of HTTPRouteRules that cannot be translated to filters for the external authorization request. Therefore, the following patterns used in HTTPRouteMatches of top-level route selectors of an AuthPolicy will not be included in the Istio AuthorizationPolicy rules that trigger the check request with Authorino: `PathMatchRegularExpression`, `HeaderMatchRegularExpression`, and `HTTPQueryParamMatch`. + +As a consequence to the above, requests that do not match these rules and otherwise would not be checked with Authorino will result in a request to the external authorization service. Authorino nonetheless will still verify those patterns and ensure the auth scheme is enforced only when it matches a selected HTTPRouteRule. Users of Kuadrant may observe an unnecessary call to the authorization service in those cases where the request is out of the scope of the AuthPolicy and therefore always authorized. - As a consequence to the above, requests that do not match these rules and otherwise would not be checked with Authorino will result in a request to the external authorization service. Authorino nonetheless will still verify those patterns and ensure the auth scheme is enforced only when it matches a selected HTTPRouteRule. Users of Kuadrant may observe an unnecessary call to the authorization service in those cases where the request is out of the scope of the AuthPolicy and therefore always authorized.
### Internal custom resources and namespaces diff --git a/doc/development.md b/doc/overviews/development.md similarity index 100% rename from doc/development.md rename to doc/overviews/development.md diff --git a/doc/dns.md b/doc/overviews/dns.md similarity index 99% rename from doc/dns.md rename to doc/overviews/dns.md index aa27e8135..06426f694 100644 --- a/doc/dns.md +++ b/doc/overviews/dns.md @@ -72,7 +72,7 @@ spec: name: headers ``` -Check out the [API reference](reference/dnspolicy.md) for a full specification of the DNSPolicy CRD. +Check out the [API reference](../reference/dnspolicy.md) for a full specification of the DNSPolicy CRD. ## Using the DNSPolicy diff --git a/doc/logging.md b/doc/overviews/logging.md similarity index 100% rename from doc/logging.md rename to doc/overviews/logging.md diff --git a/doc/rate-limiting.md b/doc/overviews/rate-limiting.md similarity index 87% rename from doc/rate-limiting.md rename to doc/overviews/rate-limiting.md index 8ef7a6aec..c54a42772 100644 --- a/doc/rate-limiting.md +++ b/doc/overviews/rate-limiting.md @@ -12,9 +12,10 @@ A Kuadrant RateLimitPolicy custom resource, often abbreviated "RateLimitPolicy": ### Envoy's Rate Limit Service Protocol Kuadrant's Rate Limit implementation relies on the Envoy's [Rate Limit Service (RLS)](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto) protocol. The workflow per request goes: + 1. On incoming request, the gateway checks the matching rules for enforcing rate limits, as stated in the RateLimitPolicy custom resources and targeted Gateway API networking objects 2. If the request matches, the gateway sends one [RateLimitRequest](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto#service-ratelimit-v3-ratelimitrequest) to the external rate limiting service ("Limitador"). -1. The external rate limiting service responds with a [RateLimitResponse](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto#service-ratelimit-v3-ratelimitresponse) back to the gateway with either an `OK` or `OVER_LIMIT` response code. +3. The external rate limiting service responds with a [RateLimitResponse](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto#service-ratelimit-v3-ratelimitresponse) back to the gateway with either an `OK` or `OVER_LIMIT` response code. A RateLimitPolicy and its targeted Gateway API networking resource contain all the statements to configure both the ingress gateway and the external rate limiting service. @@ -24,13 +25,14 @@ A RateLimitPolicy and its targeted Gateway API networking resource contain all t The `RateLimitPolicy` spec includes, basically, two parts: -* A reference to an existing Gateway API resource (`spec.targetRef`) -* Limit definitions (`spec.limits`) +- A reference to an existing Gateway API resource (`spec.targetRef`) +- Limit definitions (`spec.limits`) Each limit definition includes: -* A set of rate limits (`spec.limits..rates[]`) -* (Optional) A set of dynamic counter qualifiers (`spec.limits..counters[]`) -* (Optional) A set of additional dynamic conditions to activate the limit (`spec.limits..when[]`) + +- A set of rate limits (`spec.limits..rates[]`) +- (Optional) A set of dynamic counter qualifiers (`spec.limits..counters[]`) +- (Optional) A set of additional dynamic conditions to activate the limit (`spec.limits..when[]`) The limit definitions (`limits`) can be declared at the top-level level of the spec (with the semantics of _defaults_) or alternatively within explicit `defaults` or `overrides` blocks. @@ -81,13 +83,13 @@ spec: # routes that lack a more specific policy attached to. # Mutually exclusive with `overrides` and with declaring `limits` at the top-level of the spec. defaults: - limits: {…} + limits: { … } # Overrides. Used in policies that target a Gateway object to be enforced on all routes linked to the gateway, # thus also overriding any more specific policy occasionally attached to any of those routes. # Mutually exclusive with `defaults` and with declaring `limits` at the top-level of the spec. overrides: - limits: {…} + limits: { … } ``` ## Using the RateLimitPolicy @@ -108,7 +110,7 @@ spec: group: gateway.networking.k8s.io kind: HTTPRoute name: - limits: {…} + limits: { … } ``` ![Rate limit policy targeting a HTTPRoute resource](https://i.imgur.com/ObfOp9u.png) @@ -144,7 +146,7 @@ spec: kind: Gateway name: defaults: # alternatively: `overrides` - limits: {…} + limits: { … } ``` ![rate limit policy targeting a Gateway resource](https://i.imgur.com/UkivAqA.png) @@ -156,12 +158,14 @@ Two possible semantics are to be considered here – gateway policy _defaults_ v Gateway RateLimitPolicies that declare _defaults_ (or alternatively neither defaults nor overrides) protect all traffic routed through the gateway except where a more specific HTTPRoute RateLimitPolicy exists, in which case the HTTPRoute RateLimitPolicy prevails. Example with 4 RateLimitPolicies, 3 HTTPRoutes and 1 Gateway _default_ (plus 2 HTTPRoute and 2 Gateways without RateLimitPolicies attached): + - RateLimitPolicy A → HTTPRoute A (`a.toystore.com`) → Gateway G (`*.com`) - RateLimitPolicy B → HTTPRoute B (`b.toystore.com`) → Gateway G (`*.com`) - RateLimitPolicy W → HTTPRoute W (`*.toystore.com`) → Gateway G (`*.com`) - RateLimitPolicy G (defaults) → Gateway G (`*.com`) Expected behavior: + - Request to `a.toystore.com` → RateLimitPolicy A will be enforced - Request to `b.toystore.com` → RateLimitPolicy B will be enforced - Request to `other.toystore.com` → RateLimitPolicy W will be enforced @@ -171,12 +175,14 @@ Expected behavior: Gateway RateLimitPolicies that declare _overrides_ protect all traffic routed through the gateway, regardless of existence of any more specific HTTPRoute RateLimitPolicy. Example with 4 RateLimitPolicies, 3 HTTPRoutes and 1 Gateway _override_ (plus 2 HTTPRoute and 2 Gateways without RateLimitPolicies attached): + - RateLimitPolicy A → HTTPRoute A (`a.toystore.com`) → Gateway G (`*.com`) - RateLimitPolicy B → HTTPRoute B (`b.toystore.com`) → Gateway G (`*.com`) - RateLimitPolicy W → HTTPRoute W (`*.toystore.com`) → Gateway G (`*.com`) - RateLimitPolicy G (overrides) → Gateway G (`*.com`) Expected behavior: + - Request to `a.toystore.com` → RateLimitPolicy G will be enforced - Request to `b.toystore.com` → RateLimitPolicy G will be enforced - Request to `other.toystore.com` → RateLimitPolicy G will be enforced @@ -186,9 +192,11 @@ Expected behavior: ### Limit definition A limit will be activated whenever a request comes in and the request matches: + - all of the `when` conditions specified in the limit. A limit can define: + - counters that are qualified based on dynamic values fetched from the request, or - global counters (implicitly, when no qualified counter is specified) @@ -201,31 +209,31 @@ spec: limits: "toystore-all": rates: - - limit: 5000 - window: 1s + - limit: 5000 + window: 1s "toystore-api-per-username": rates: - - limit: 100 - window: 1s - - limit: 1000 - window: 1m + - limit: 100 + window: 1s + - limit: 1000 + window: 1m counters: - - expression: auth.identity.username + - expression: auth.identity.username when: - - predicate: request.host == 'api.toystore.com' + - predicate: request.host == 'api.toystore.com' "toystore-admin-unverified-users": rates: - - limit: 250 - window: 1s + - limit: 250 + window: 1s when: - - predicate: request.host == 'admin.toystore.com' - - predicate: !auth.identity.email_verified + - predicate: request.host == 'admin.toystore.com' + - predicate: !auth.identity.email_verified ``` | Request to | Rate limits enforced | -|----------------------|--------------------------------------------------------------| +| -------------------- | ------------------------------------------------------------ | | `api.toystore.com` | 100rps/username or 1000rpm/username (whatever happens first) | | `admin.toystore.com` | 250rps | | `other.toystore.com` | 5000rps | @@ -241,26 +249,28 @@ The selectors within the `when` conditions of a RateLimitPolicy are a subset of ### Examples Check out the following user guides for examples of rate limiting services with Kuadrant: -* [Simple Rate Limiting for Application Developers](user-guides/simple-rl-for-app-developers.md) -* [Authenticated Rate Limiting for Application Developers](user-guides/authenticated-rl-for-app-developers.md) -* [Gateway Rate Limiting for Cluster Operators](user-guides/gateway-rl-for-cluster-operators.md) -* [Authenticated Rate Limiting with JWTs and Kubernetes RBAC](user-guides/authenticated-rl-with-jwt-and-k8s-authnz.md) + +- [Simple Rate Limiting for Applications](../user-guides/ratelimiting/simple-rl-for-app-developers.md) +- [Authenticated Rate Limiting for Application](../user-guides/ratelimiting/authenticated-rl-for-app-developers.md) +- [Gateway Rate Limiting for Cluster Operators](../user-guides/ratelimiting/gateway-rl-for-cluster-operators.md) +- [Authenticated Rate Limiting with JWTs and Kubernetes RBAC](../user-guides/ratelimiting/authenticated-rl-with-jwt-and-k8s-authnz.md) ### Known limitations -* RateLimitPolicies can only target HTTPRoutes/Gateways defined within the same namespace of the RateLimitPolicy. -* 2+ RateLimitPolicies cannot target network resources that define/inherit the same exact hostname. +- RateLimitPolicies can only target HTTPRoutes/Gateways defined within the same namespace of the RateLimitPolicy. +- 2+ RateLimitPolicies cannot target network resources that define/inherit the same exact hostname. ## Implementation details Driven by limitations related to how Istio injects configuration in the filter chains of the ingress gateways, Kuadrant relies on Envoy's [Wasm Network](https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/wasm_filter) filter in the data plane, to manage the integration with rate limiting service ("Limitador"), instead of the [Rate Limit](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter) filter. -**Motivation:** _Multiple rate limit domains_
+**Motivation:** _Multiple rate limit domains_ + The first limitation comes from having only one filter chain per listener. This often leads to one single global rate limiting filter configuration per gateway, and therefore to a shared rate limit [domain](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ratelimit/v3/rate_limit.proto#envoy-v3-api-msg-extensions-filters-http-ratelimit-v3-ratelimit) across applications and policies. Even though, in a rate limit filter, the triggering of rate limit calls, via [actions to build so-called "descriptors"](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter#composing-actions), can be defined at the level of the virtual host and/or specific route rule, the overall rate limit configuration is only one, i.e., always the same rate limit domain for all calls to Limitador. On the other hand, the possibility to configure and invoke the rate limit service for multiple domains depending on the context allows to isolate groups of policy rules, as well as to optimize performance in the rate limit service, which can rely on the domain for indexation. -**Motivation:** _Fine-grained matching rules_
+**Motivation:** _Fine-grained matching rules_ A second limitation of configuring the rate limit filter via Istio, particularly from [Gateway API](https://gateway-api.sigs.k8s.io) resources, is that [rate limit descriptors](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter#composing-actions) at the level of a specific HTTP route rule require "named routes" – defined only in an Istio [VirtualService](https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRoute) resource and referred in an [EnvoyFilter](https://istio.io/latest/docs/reference/config/networking/envoy-filter/#EnvoyFilter-RouteConfigurationMatch-RouteMatch) one. Because Gateway API HTTPRoute rules lack a "name" property[^1], as well as the Istio VirtualService resources are only ephemeral data structures handled by Istio in-memory in its implementation of gateway configuration for Gateway API, where the names of individual route rules are auto-generated and not referable by users in a policy[^2][^3], rate limiting by attributes of the HTTP request (e.g., path, method, headers, etc) would be very limited while depending only on Envoy's [Rate Limit](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter) filter. [^1]: https://github.com/kubernetes-sigs/gateway-api/pull/996 @@ -272,6 +282,7 @@ Motivated by the desire to support multiple rate limit domains per ingress gatew The wasm module integrates with the gateway in the data plane via [Wasm Network](https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/wasm_filter) filter, and parses a configuration composed out of user-defined RateLimitPolicy resources by the Kuadrant control plane. Whereas the rate limiting service ("Limitador") remains an implementation of Envoy's RLS protocol, capable of being integrated directly via [Rate Limit](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/ratelimit/v3/rate_limit.proto#extension-envoy-filters-network-ratelimit) extension or by Kuadrant, via wasm module for the [Istio Gateway API implementation](https://gateway-api.sigs.k8s.io/implementations/#istio). As a consequence of this design: + - Users can define fine-grained rate limit rules that match their Gateway and HTTPRoute definitions including for subsections of these. - Rate limit definitions are insulated, not leaking across unrelated policies or applications. - Conditions to activate limits are evaluated in the context of the gateway process, reducing the gRPC calls to the external rate limiting service only to the cases where rate limit counters are known in advance to have to be checked/incremented. @@ -289,12 +300,12 @@ metadata: name: kuadrant-kuadrant-ingressgateway namespace: gateway-system ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1 - blockOwnerDeletion: true - controller: true - kind: Gateway - name: kuadrant-ingressgateway - uid: 0298355b-fb30-4442-af2b-88d0c05bd2bd + - apiVersion: gateway.networking.k8s.io/v1 + blockOwnerDeletion: true + controller: true + kind: Gateway + name: kuadrant-ingressgateway + uid: 0298355b-fb30-4442-af2b-88d0c05bd2bd resourceVersion: "11253" uid: 36ef1fb7-9eca-46c7-af63-fe783f40148c spec: @@ -308,37 +319,37 @@ spec: actionSets: - name: some_name_0 routeRuleConditions: - hostnames: - - '*.toystore.website' - - '*.toystore.io' + hostnames: + - "*.toystore.website" + - "*.toystore.io" predicates: - - request.url_path.startsWith("/assets") + - request.url_path.startsWith("/assets") actions: - - service: ratelimit-service - scope: gateway-system/app-rlp - predicates: - - request.host.endsWith('.toystore.website') - data: - - expression: - key: limit.toystore_assets_all_domains__b61ee8e6 - value: "1" + - service: ratelimit-service + scope: gateway-system/app-rlp + predicates: + - request.host.endsWith('.toystore.website') + data: + - expression: + key: limit.toystore_assets_all_domains__b61ee8e6 + value: "1" - name: some_name_1 routeRuleConditions: - hostnames: - - '*.toystore.website' - - '*.toystore.io' + hostnames: + - "*.toystore.website" + - "*.toystore.io" predicates: - - request.url_path.startsWith("/v1") + - request.url_path.startsWith("/v1") actions: - - service: ratelimit-service - scope: gateway-system/app-rlp - predicates: - - request.host.endsWith('.toystore.website') - - auth.identity.username == "" - data: - - expression: - key: limit.toystore_v1_website_unauthenticated__377837ee - value: "1" + - service: ratelimit-service + scope: gateway-system/app-rlp + predicates: + - request.host.endsWith('.toystore.website') + - auth.identity.username == "" + data: + - expression: + key: limit.toystore_v1_website_unauthenticated__377837ee + value: "1" targetRef: group: gateway.networking.k8s.io kind: Gateway diff --git a/doc/tls.md b/doc/overviews/tls.md similarity index 78% rename from doc/tls.md rename to doc/overviews/tls.md index 10807e5af..64b9fdbf2 100644 --- a/doc/tls.md +++ b/doc/overviews/tls.md @@ -2,7 +2,7 @@ A Kuadrant TLSPolicy custom resource: -1. Targets Gateway API networking resources [Gateways](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway) to provide tls for gateway listeners by managing the lifecycle of tls certificates using [`CertManager`](https://cert-manager.io). +Targets Gateway API networking resources [Gateways](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway) to provide tls for gateway listeners by managing the lifecycle of tls certificates using [`CertManager`](https://cert-manager.io). ## How it works @@ -37,7 +37,7 @@ spec: name: mygateway ``` -Check out the [API reference](reference/tlspolicy.md) for a full specification of the TLSPolicy CRD. +Check out the [API reference](../reference/tlspolicy.md) for a full specification of the TLSPolicy CRD. ## Using the TLSPolicy diff --git a/doc/reference/ratelimitpolicy.md b/doc/reference/ratelimitpolicy.md index 105cea20c..ab2de0205 100644 --- a/doc/reference/ratelimitpolicy.md +++ b/doc/reference/ratelimitpolicy.md @@ -11,11 +11,31 @@ | **Field** | **Type** | **Required** | **Description** | |-------------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `targetRef` | [LocalPolicyTargetReference](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReference) | Yes | Reference to a Kubernetes resource that the policy attaches to | +| `targetRef` | [LocalPolicyTargetReferenceWithSectionName](#localpolicytargetreferencewithsectionname) | Yes | Reference to a Kubernetes resource that the policy attaches to. For more [info](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReference) | | `defaults` | [RateLimitPolicyCommonSpec](#rateLimitPolicyCommonSpec) | No | Default limit definitions. This field is mutually exclusive with the `limits` field | | `overrides` | [RateLimitPolicyCommonSpec](#rateLimitPolicyCommonSpec) | No | Overrides limit definitions. This field is mutually exclusive with the `limits` field and `defaults` field. This field is only allowed for policies targeting `Gateway` in `targetRef.kind` | | `limits` | Map | No | Limit definitions. This field is mutually exclusive with the [`defaults`](#rateLimitPolicyCommonSpec) field | + + + +### LocalPolicyTargetReferenceWithSectionName +| **Field** | **Type** | **Required** | **Description** | +|------------------|-----------------------------------------|--------------|------------------------------------------------------------| +| `LocalPolicyTargetReference` | [LocalPolicyTargetReference](#localpolicytargetreference) | Yes | Reference to a local policy target. | +| `sectionName` | [SectionName](#sectionname) | No | Section name for further specificity (if needed). | + +### LocalPolicyTargetReference +| **Field** | **Type** | **Required** | **Description** | +|-----------|--------------|--------------|--------------------------------| +| `group` | `Group` | Yes | Group of the target resource. | +| `kind` | `Kind` | Yes | Kind of the target resource. | +| `name` | `ObjectName` | Yes | Name of the target resource. | + +### SectionName +| Field | Type | Required | Description | +|-------------|--------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| SectionName | v1.SectionName (String) | Yes | SectionName is the name of a section in a Kubernetes resource.
In the following resources, SectionName is interpreted as the following:
* Gateway: Listener name
* HTTPRoute: HTTPRouteRule name
* Service: Port name | ### RateLimitPolicyCommonSpec | **Field** | **Type** | **Required** | **Description** | diff --git a/doc/user-guides/auth-for-app-devs-and-platform-engineers.md b/doc/user-guides/auth/auth-for-app-devs-and-platform-engineers.md similarity index 90% rename from doc/user-guides/auth-for-app-devs-and-platform-engineers.md rename to doc/user-guides/auth/auth-for-app-devs-and-platform-engineers.md index 83b4a4e8f..04c0d22db 100644 --- a/doc/user-guides/auth-for-app-devs-and-platform-engineers.md +++ b/doc/user-guides/auth/auth-for-app-devs-and-platform-engineers.md @@ -5,7 +5,7 @@ This guide walks you through the process of setting up a local Kubernetes cluste Three AuthPolicies will be declared: | Use case | AuthPolicies | -|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **App developer** | 2 AuthPolicies targeting a HTTPRoute that routes traffic to a sample "Toy Store" application → enforce API key authentication to all requests in this route; require API key owners to be mapped to `groups:admins` metadata to access a specific HTTPRouteRule of the route. | | **Platform engineer use-case** | 1 AuthPolicy targeting the `kuadrant-ingressgateway` Gateway → enforces a trivial "deny-all" policy that locks down any other HTTPRoute attached to the Gateway. | @@ -35,39 +35,12 @@ Topology: └─────────────────┘ ``` -## Requisites +## Setup the environment -- [Docker](https://docker.io) +Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make-target.md) to set up your environment before continuing with this doc. -## Run the guide ① → ④ -### ① Setup (Persona: _Cluster admin_) - -Clone the repo: - -```sh -git clone git@github.com:Kuadrant/kuadrant-operator.git && cd kuadrant-operator -``` - -Run the following command to create a local Kubernetes cluster with [Kind](https://kind.sigs.k8s.io/), install & deploy Kuadrant: - -```sh -make local-setup -``` - -Request an instance of Kuadrant in the `kuadrant-system` namespace: - -```sh -kubectl -n kuadrant-system apply -f - <Note: These resources are for view only interactions as they are controlled by the Kuadrant Operator based on the DNSPolicy API +>**Note**: These resources are for view only interactions as they are controlled by the Kuadrant Operator based on the DNSPolicy API ```bash kubectl get dnshealthcheckprobes n my-dns-policy-namespace -o=wide diff --git a/doc/user-guides/gateway-dns.md b/doc/user-guides/dns/gateway-dns.md similarity index 89% rename from doc/user-guides/gateway-dns.md rename to doc/user-guides/dns/gateway-dns.md index 078cffee2..804862359 100644 --- a/doc/user-guides/gateway-dns.md +++ b/doc/user-guides/dns/gateway-dns.md @@ -1,47 +1,33 @@ -# Gateway DNS for Cluster Operators +# Gateway DNS configuration for routes attached to a ingress gateway This user guide walks you through an example of how to configure DNS for all routes attached to an ingress gateway. -
- ## Requisites - [Docker](https://docker.io) - [Rout53 Hosted Zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingHostedZone.html) -### Setup - -This step uses tooling from the Kuadrant Operator component to create a containerized Kubernetes server locally using [Kind](https://kind.sigs.k8s.io), -where it installs Istio, Kubernetes Gateway API and Kuadrant itself. - -Clone the project: - -```shell -git clone https://github.com/Kuadrant/kuadrant-operator && cd kuadrant-operator -``` - -Setup the environment: +### Setup the environment -```shell -make local-setup -``` +Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make-target.md) to set up your environment before continuing with this doc. Create a namespace: + ```shell kubectl create namespace my-gateways ``` Export a root domain and hosted zone id: + ```shell export ROOT_DOMAIN= ``` -> **Note:** ROOT_DOMAIN should be set to your AWS hosted zone *name*. +> **Note:** ROOT_DOMAIN should be set to your AWS hosted zone _name_. ### Create a dns provider secret -Create AWS provider secret. You should limit the permissions of this credential to only the zones you want us to access. - +Create AWS provider secret. You should limit the permissions of this credential to only the zones you want us to access. ```shell export AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= @@ -55,6 +41,7 @@ kubectl -n my-gateways create secret generic aws-credentials \ ### Create an ingress gateway Create a gateway using your ROOT_DOMAIN as part of a listener hostname: + ```sh kubectl -n my-gateways apply -f - <**Note:** If you are running on a local kind cluster, it is also recommended you use [metallb](https://metallb.universe.tf/) to setup an IP address pool to use with loadbalancer services for your gateways. An example script for configuring metallb based on the docker network once installed can be found [here](https://github.com/Kuadrant/kuadrant-operator/blob/main/utils/docker-network-ipaddresspool.sh). +> **Note:** If you are running on a local kind cluster, it is also recommended you use [metallb](https://metallb.universe.tf/) to setup an IP address pool to use with loadbalancer services for your gateways. An example script for configuring metallb based on the docker network once installed can be found [here](https://github.com/Kuadrant/kuadrant-operator/blob/main/utils/docker-network-ipaddresspool.sh). ``` ./utils/docker-network-ipaddresspool.sh kind yq 1 | kubectl apply -n metallb-system -f - @@ -19,29 +18,21 @@ In this guide, we will cover the different policies from Kuadrant and how you ca Here are the steps we will go through: -1) [Deploy a sample application](#deploy-the-example-app-we-will-serve-via-our-gateway) - - -2) [Define a new Gateway](#define-a-new-istio-managed-gateway) - - -3) [Ensure TLS-based secure connectivity to the gateway with a TLSPolicy](#define-the-tlspolicy) - +1. [Deploy a sample application](#deploy-the-example-app-we-will-serve-via-our-gateway) -4) [Define a default RateLimitPolicy to set some infrastructure limits on your gateway](#define-infrastructure-rate-limiting) +2. [Define a new Gateway](#define-a-new-istio-managed-gateway) +3. [Ensure TLS-based secure connectivity to the gateway with a TLSPolicy](#define-the-tlspolicy) -5) [Define a default AuthPolicy to deny all access to the gateway](#define-the-gateway-authpolicy) +4. [Define a default RateLimitPolicy to set some infrastructure limits on your gateway](#define-infrastructure-rate-limiting) +5. [Define a default AuthPolicy to deny all access to the gateway](#define-the-gateway-authpolicy) -6) [Define a DNSPolicy to bring traffic to the gateway](#define-the-dnspolicy) +6. [Define a DNSPolicy to bring traffic to the gateway](#define-the-dnspolicy) +7. [Override the Gateway's deny-all AuthPolicy with an endpoint-specific policy](#override-the-gateways-deny-all-authpolicy) -7) [Override the Gateway's deny-all AuthPolicy with an endpoint-specific policy](#override-the-gateways-deny-all-authpolicy) - - -8) [Override the Gateway rate limits with an endpoint-specific policy](#override-the-gateways-ratelimitpolicy) - +8. [Override the Gateway rate limits with an endpoint-specific policy](#override-the-gateways-ratelimitpolicy) You will need to set the `KUBECTL_CONTEXT` environment variable for the kubectl context of the cluster you are targeting. @@ -65,13 +56,13 @@ To help with this walk through, you should also set a `KUADRANT_ZONE_ROOT_DOMAIN export KUADRANT_ZONE_ROOT_DOMAIN=my.domain.iown ``` -### ❶ Deploy the example app we will serve via our gateway +### Deploy the example app we will serve via our gateway ```sh kubectl --context $KUBECTL_CONTEXT apply -f https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/main/examples/toystore/toystore.yaml ``` -### ❷ Define a new Istio-managed gateway +### Define a new Istio-managed gateway ```sh kubectl --context $KUBECTL_CONTEXT apply -f - < **Note:** If you have followed through this guide on more than 1 cluster, the DNS record for the HTTPRoute hostname will have multiple IP addresses. This means that requests will be made in a round robin pattern across clusters as your DNS provider sends different responses to lookups. You may need to send multiple requests before one hits the cluster you are currently configuring. @@ -372,7 +362,7 @@ With DNS in place, let's test it again. This time we expect a `403` still as the curl -k "https://api.$KUADRANT_ZONE_ROOT_DOMAIN/cars" -i ``` -### ❼ Override the Gateway's deny-all AuthPolicy +### Override the Gateway's deny-all AuthPolicy Next, we are going to allow authenticated access to our Toystore API. To do this, we will define an AuthPolicy that targets the HTTPRoute. Note that any new HTTPRoutes will still be affected by the gateway-level policy, but as we want users to now access this API, we need to override that policy. For simplicity, we will use API keys to authenticate the requests, though many other options are available. @@ -450,7 +440,7 @@ Ensure the new policy is enforced: kubectl --context $KUBECTL_CONTEXT wait authpolicy toystore --for=condition=enforced ``` -### ❽ Override the Gateway's RateLimitPolicy +### Override the Gateway's RateLimitPolicy The gateway limits are a good set of limits for the general case, but as the developers of this API we know that we only want to allow a certain number of requests to specific users, and a general limit for all other users. diff --git a/doc/user-guides/secure-protect-connect-single-multi-cluster.md b/doc/user-guides/full-walkthrough/secure-protect-connect-openshift.md similarity index 98% rename from doc/user-guides/secure-protect-connect-single-multi-cluster.md rename to doc/user-guides/full-walkthrough/secure-protect-connect-openshift.md index ffa292684..060ca45f9 100644 --- a/doc/user-guides/secure-protect-connect-single-multi-cluster.md +++ b/doc/user-guides/full-walkthrough/secure-protect-connect-openshift.md @@ -29,10 +29,10 @@ While this document uses `kubectl` commands for simplicity, working with multipl This guide expects that you have successfully installed Kuadrant on at least one OpenShift cluster: -- You have completed the steps in [Install Kuadrant on an OpenShift cluster](../install/install-openshift.md) for one or more clusters. +- You have completed the steps in [Install Kuadrant on an OpenShift cluster](../../install/install-openshift.md) for one or more clusters. - For multicluster scenarios, you have installed Kuadrant on at least two different OpenShift clusters, and have a shared accessible Redis store. - You have the `kubectl` command line installed. -- Optional: User workload monitoring is configured to remote write to a central storage system such as Thanos, as described in [Install Kuadrant on an OpenShift cluster](../install/install-openshift.md). +- Optional: User workload monitoring is configured to remote write to a central storage system such as Thanos, as described in [Install Kuadrant on an OpenShift cluster](../../install/install-openshift.md). ## Platform engineer workflow @@ -443,9 +443,9 @@ kubectl apply -f https://raw.githubusercontent.com/Kuadrant/Kuadrant-operator/ma Copy at least one of the following example OAS to a local location: -- [Sample OAS for rate limiting with API key](../../examples/oas-apikey.yaml) +- [Sample OAS for rate limiting with API key](../../../examples/oas-apikey.yaml) -- [Sample OAS for rate limiting with OIDC](../../examples/oas-oidc.yaml) +- [Sample OAS for rate limiting with OIDC](../../../examples/oas-oidc.yaml) Set up some new environment variables as follows: @@ -570,7 +570,7 @@ The example OAS uses Kuadrant-based extensions. These extensions enable you to d - You have installed and configured an OpenID Connect provider, such as . - You have a realm, client, and users set up. This example assumes a realm in a Keycloak instance called `toystore`. -- Copy the OAS from [sample OAS for rate-limiting and OIDC](../../examples/oas-oidc.yaml) to a local location. +- Copy the OAS from [sample OAS for rate-limiting and OIDC](../../../examples/oas-oidc.yaml) to a local location. #### Set up an OpenID AuthPolicy @@ -634,7 +634,7 @@ You should see a `200` response code. ### Step 7 - Set up rate limiting -Lastly, you can generate your `RateLimitPolicy` to add your rate limits, based on your OAS file. Rate limiting is simplified for this walkthrough and is based on either the bearer token or the API key value. There are more advanced examples in the How-to guides on the Kuadrant documentation site, for example: [Authenticated rate limiting with JWTs and Kubernetes RBAC](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/authenticated-rl-with-jwt-and-k8s-authnz/). +Lastly, you can generate your `RateLimitPolicy` to add your rate limits, based on your OAS file. Rate limiting is simplified for this walkthrough and is based on either the bearer token or the API key value. There are more advanced examples in the How-to guides on the Kuadrant documentation site, for example: [Authenticated rate limiting with JWTs and Kubernetes RBAC](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/ratelimiting/authenticated-rl-with-jwt-and-k8s-authnz/). You can continue to use this sample OAS document, which includes both authentication and a rate limit: diff --git a/doc/user-guides/external-api.md b/doc/user-guides/misc/external-api.md similarity index 96% rename from doc/user-guides/external-api.md rename to doc/user-guides/misc/external-api.md index 335ab7c8b..5aea54700 100644 --- a/doc/user-guides/external-api.md +++ b/doc/user-guides/misc/external-api.md @@ -82,11 +82,11 @@ EOF 2) Optional: Use TLSPolicy to configure TLS certificates for your listeners -[TLSPolicy Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/gateway-tls/) +[TLSPolicy Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/tls/gateway-tls/) 3) Optional: Use DNSPolicy to bring external traffic to the external hostname -[DNSPolicy Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/gateway-dns/#create-a-dns-provider-secret) +[DNSPolicy Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/dns/gateway-dns/#create-a-dns-provider-secret) 4) Ensure the Gateway has the status of `Programmed` set to `True` meaning it is ready. @@ -170,7 +170,7 @@ We should now be able to send requests to our external host and have the Gateway As we are using Gateway API to define the Gateway and HTTPRoutes, we can now also apply RateLimiting and Auth to protect our public endpoints -[AuthPolicy Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/auth-for-app-devs-and-platform-engineers/) +[AuthPolicy Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/auth/auth-for-app-devs-and-platform-engineers/) -[RateLimiting Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/gateway-rl-for-cluster-operators/) +[RateLimiting Guide](https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/ratelimting/multi-rlp-multi-listener/) diff --git a/doc/user-guides/authenticated-rl-for-app-developers.md b/doc/user-guides/ratelimiting/authenticated-rl-for-app-developers.md similarity index 85% rename from doc/user-guides/authenticated-rl-for-app-developers.md rename to doc/user-guides/ratelimiting/authenticated-rl-for-app-developers.md index d9ee27e17..8aeb82e18 100644 --- a/doc/user-guides/authenticated-rl-for-app-developers.md +++ b/doc/user-guides/ratelimiting/authenticated-rl-for-app-developers.md @@ -1,4 +1,5 @@ -# Authenticated Rate Limiting for Application Developers +# Authenticated Rate Limiting for Application developers +For more info on the different personas see [Gateway API](https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#key-roles-and-personas) This user guide walks you through an example of how to configure authenticated rate limiting for an application using Kuadrant. @@ -13,44 +14,15 @@ In this guide, we will rate limit a sample REST API called **Toy Store**. In rea We will define 2 users of the API, which can send requests to the API at different rates, based on their user IDs. The authentication method used is **API key**. | User ID | Rate limit | -|---------|----------------------------------------| +| ------- | -------------------------------------- | | alice | 5rp10s ("5 requests every 10 seconds") | | bob | 2rp10s ("2 requests every 10 seconds") | -## Run the steps ① → ④ +### Setup the environment -### ① Setup +Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make-target.md) to set up your environment before continuing with this doc. -This step uses tooling from the Kuadrant Operator component to create a containerized Kubernetes server locally using [Kind](https://kind.sigs.k8s.io), -where it installs Istio, Kubernetes Gateway API and Kuadrant itself. - -> **Note:** In production environment, these steps are usually performed by a cluster operator with administrator privileges over the Kubernetes cluster. - -Clone the project: - -```sh -git clone https://github.com/Kuadrant/kuadrant-operator && cd kuadrant-operator -``` - -Setup the environment: - -```sh -make local-setup -``` - -Request an instance of Kuadrant: - -```sh -kubectl -n kuadrant-system apply -f - < kubectl port-forward -n gateway-system service/kuadrant-ingressgateway-istio 9080:80 >/dev/null 2>&1 & > export GATEWAY_URL=localhost:9080 > ``` +> > ```sh > curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy -i > # HTTP/1.1 200 OK > ``` -### ③ Enforce authentication on requests to the Toy Store API +### Enforce authentication on requests to the Toy Store API Create a Kuadrant `AuthPolicy` to configure the authentication: @@ -192,7 +165,7 @@ type: Opaque EOF ``` -### ④ Enforce authenticated rate limiting on requests to the Toy Store API +### Enforce authenticated rate limiting on requests to the Toy Store API Create a Kuadrant `RateLimitPolicy` to configure rate limiting: diff --git a/doc/user-guides/authenticated-rl-with-jwt-and-k8s-authnz.md b/doc/user-guides/ratelimiting/authenticated-rl-with-jwt-and-k8s-authnz.md similarity index 82% rename from doc/user-guides/authenticated-rl-with-jwt-and-k8s-authnz.md rename to doc/user-guides/ratelimiting/authenticated-rl-with-jwt-and-k8s-authnz.md index e97152867..d566227e2 100644 --- a/doc/user-guides/authenticated-rl-with-jwt-and-k8s-authnz.md +++ b/doc/user-guides/ratelimiting/authenticated-rl-with-jwt-and-k8s-authnz.md @@ -16,66 +16,23 @@ Any authenticated user/service account can send requests to the Toy Store API, b Privileges to execute the requested operation (read, create or delete) will be granted according to the following RBAC rules, stored in the Kubernetes authorization system: | Operation | Endpoint | Required role | -|-----------|---------------------|-------------------| +| --------- | ------------------- | ----------------- | | Read | `GET /toy*` | `toystore-reader` | | Create | `POST /admin/toy` | `toystore-write` | | Delete | `DELETE /admin/toy` | `toystore-write` | Each user will be entitled to a maximum of 5rp10s (5 requests every 10 seconds). -## Requirements +### Setup the environment -- [Docker](https://www.docker.com/) -- [kubectl](https://kubernetes.io/docs/reference/kubectl/) command-line tool -- [jq](https://stedolan.github.io/jq/) +Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make-target.md) to set up your environment before continuing with this doc. -## Run the guide ① → ⑥ - -### ① Setup a cluster with Kuadrant - -This step uses tooling from the Kuadrant Operator component to create a containerized Kubernetes server locally using [Kind](https://kind.sigs.k8s.io), -where it installs Istio, Kubernetes Gateway API and Kuadrant itself. - -> **Note:** In production environment, these steps are usually performed by a cluster operator with administrator privileges over the Kubernetes cluster. - -Clone the project: - -```sh -git clone https://github.com/Kuadrant/kuadrant-operator && cd kuadrant-operator -``` - -Setup the environment: - -```sh -make local-setup -``` - -Request an instance of Kuadrant: - -```sh -kubectl -n kuadrant-system apply -f - < kubectl port-forward -n gateway-system service/kuadrant-ingressgateway-istio 9080:80 >/dev/null 2>&1 & > export GATEWAY_URL=localhost:9080 > ``` +> > ```sh > curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy -i > # HTTP/1.1 200 OK > ``` -### ③ Deploy Keycloak +### Deploy Keycloak Create the namesapce: @@ -124,7 +82,7 @@ kubectl apply -n keycloak -f https://raw.githubusercontent.com/Kuadrant/authorin > **Note:** The Keycloak server may take a couple of minutes to be ready. -### ④ Enforce authentication and authorization for the Toy Store API +### Enforce authentication and authorization for the Toy Store API Create a Kuadrant `AuthPolicy` to configure authentication and authorization: @@ -216,7 +174,7 @@ curl -H "Authorization: Bearer $SA_TOKEN" -H 'Host: api.toystore.com' http://$GA # HTTP/1.1 403 Forbidden ``` -### ⑤ Grant access to the Toy Store API for user and service account +### Grant access to the Toy Store API for user and service account Create the `toystore-reader` and `toystore-writer` roles: @@ -243,7 +201,7 @@ EOF Add permissions to the user and service account: | User | Kind | Roles | -|--------------|-----------------------------|--------------------------------------| +| ------------ | --------------------------- | ------------------------------------ | | john | User registered in Keycloak | `toystore-reader`, `toystore-writer` | | client-app-1 | Kuberentes Service Account | `toystore-reader` | @@ -281,12 +239,13 @@ EOF
Q: Can I use Roles and RoleBindings instead of ClusterRoles and ClusterRoleBindings? - Yes, you can. +Yes, you can. + +The example above is for non-resource URL Kubernetes roles. For using `Roles` and `RoleBindings` instead of +`ClusterRoles` and `ClusterRoleBindings`, thus more flexible resource-based permissions to protect the API, +see the spec for [Kubernetes SubjectAccessReview authorization](https://docs.kuadrant.io/latest/authorino/docs/features/#kubernetes-subjectaccessreview-authorizationkubernetessubjectaccessreview) +in the Authorino docs. - The example above is for non-resource URL Kubernetes roles. For using `Roles` and `RoleBindings` instead of - `ClusterRoles` and `ClusterRoleBindings`, thus more flexible resource-based permissions to protect the API, - see the spec for [Kubernetes SubjectAccessReview authorization](https://docs.kuadrant.io/latest/authorino/docs/features/#kubernetes-subjectaccessreview-authorizationkubernetessubjectaccessreview) - in the Authorino docs.
#### Try the API with permission @@ -315,7 +274,7 @@ curl -H "Authorization: Bearer $SA_TOKEN" -H 'Host: api.toystore.com' -X POST ht # HTTP/1.1 403 Forbidden ``` -### ⑥ Enforce rate limiting on requests to the Toy Store API +### Enforce rate limiting on requests to the Toy Store API Create a Kuadrant `RateLimitPolicy` to configure rate limiting: diff --git a/doc/user-guides/gateway-rl-for-cluster-operators.md b/doc/user-guides/ratelimiting/gateway-rl-for-cluster-operators.md similarity index 80% rename from doc/user-guides/gateway-rl-for-cluster-operators.md rename to doc/user-guides/ratelimiting/gateway-rl-for-cluster-operators.md index a32586c25..3619317d6 100644 --- a/doc/user-guides/gateway-rl-for-cluster-operators.md +++ b/doc/user-guides/ratelimiting/gateway-rl-for-cluster-operators.md @@ -1,43 +1,21 @@ # Gateway Rate Limiting for Cluster Operators -This user guide walks you through an example of how to configure rate limiting for all routes attached to an ingress gateway. +For more info on the different personas see [Gateway API](https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#key-roles-and-personas) -
+This user guide walks you through an example of how to configure rate limiting for all routes attached to a specific ingress gateway. -## Run the steps ① → ⑤ -### ① Setup +### Setup the environment -This step uses tooling from the Kuadrant Operator component to create a containerized Kubernetes server locally using [Kind](https://kind.sigs.k8s.io), -where it installs Istio, Kubernetes Gateway API and Kuadrant itself. +Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make-target.md) to set up your environment before continuing with this doc. -> **Note:** In production environment, these steps are usually performed by a cluster operator with administrator privileges over the Kubernetes cluster. - -Clone the project: +### Deploy the Toystore example API: ```sh -git clone https://github.com/Kuadrant/kuadrant-operator && cd kuadrant-operator -``` - -Setup the environment: +kubectl apply -f examples/toystore/toystore.yaml -```sh -make local-setup ``` - -Request an instance of Kuadrant: - -```sh -kubectl -n kuadrant-system apply -f - < **Note:** It may take a couple of minutes for the RateLimitPolicy to be applied depending on your cluster. -### ④ Deploy a sample API to test rate limiting enforced at the level of the gateway +### Deploy a sample API to test rate limiting enforced at the level of the gateway ``` ┌───────────┐ ┌───────────┐ @@ -145,13 +123,7 @@ EOF └──────────────┘ ``` -Deploy the sample API: - -```sh -kubectl apply -f examples/toystore/toystore.yaml -``` - -Route traffic to the API from both gateways: +### Route traffic to the API from both gateways: ```sh kubectl apply -f - < **Note:** It may take a couple of minutes for the RateLimitPolicy to be applied depending on your cluster. + + + +### Verify the rate limiting works by sending requests in a loop + +Expose the gateways, respectively at the port numbers `9081` and `9082` of the local host: + +```sh +kubectl port-forward -n gateway-system service/environment-istio 9081:80 >/dev/null 2>&1 & +``` + +Up to 5 successful (`200 OK`) requests every 10 seconds through the `external` ingress gateway (`*.io`), then `429 Too Many Requests`: + +```sh +while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Host: api.toystore.io' http://localhost:9081 | grep -E --color "\b(429)\b|$"; sleep 1; done +``` + +Unlimited successful (`200 OK`) through the `internal` ingress gateway (`*.local`): + +```sh +while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Host: api.toystore.local' http://localhost:9081 | grep -E --color "\b(429)\b|$"; sleep 1; done +``` + +## Cleanup + +```sh +make local-cleanup +``` diff --git a/doc/user-guides/ratelimiting/multi-auth-rlp-same-section.md b/doc/user-guides/ratelimiting/multi-auth-rlp-same-section.md new file mode 100644 index 000000000..ef972f227 --- /dev/null +++ b/doc/user-guides/ratelimiting/multi-auth-rlp-same-section.md @@ -0,0 +1,244 @@ +# Multi authenticated Rate Limiting for an Application + +This user guide walks you through an example of how to configure multiple authenticated rate limiting for an application using Kuadrant. + +Authenticated rate limiting, rate limits the traffic directed to an application based on attributes of the client user, who is authenticated by some authentication method. A few examples of authenticated rate limiting use cases are: + +- User A can send up to 50rps ("requests per second"), while User B can send up to 100rps. +- Each user can send up to 20rpm ("request per minute"). +- Admin users (members of the 'admin' group) can send up to 100rps, while regular users (non-admins) can send up to 20rpm and no more than 5rps. + +In this guide, we will rate limit a sample REST API called **Toy Store**, an echo service that echoes back to the user whatever attributes it gets in the request. The API exposes an endpoint at `GET http://api.toystore.com/toy`, to mimic an operation of reading toy records. + +We will define 2 users of the API, which can send requests to the API at different rates, based on their user IDs. The authentication method used is **API key**. + +| User ID | Rate limit | +| ------- | -------------------------------------- | +| alice | 5rp10s ("5 requests every 10 seconds") | +| bob | 2rp10s ("2 requests every 10 seconds") | + +### Setup the environment + +Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make-target.md) to set up your environment before continuing with this doc. + +### Deploy the Toy Store API + +```sh +kubectl apply -f examples/toystore/toystore.yaml +``` + +### Create a HTTPRoute to route traffic to the service via Istio Ingress Gateway: + +![](https://i.imgur.com/rdN8lo3.png) + +```sh +kubectl apply -f - < **Note**: If the command above fails to hit the Toy Store API on your environment, try forwarding requests to the service and accessing over localhost: +> +> ```sh +> kubectl port-forward -n gateway-system service/kuadrant-ingressgateway-istio 9080:80 >/dev/null 2>&1 & +> export GATEWAY_URL=localhost:9080 +> ``` +> +> ```sh +> curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy -i +> # HTTP/1.1 200 OK +> ``` + +### Enforce authentication on requests to the Toy Store API + +Create a Kuadrant `AuthPolicy` to configure the authentication: + +```sh +kubectl apply -f - < **Note:** Kuadrant stores API keys as Kubernetes Secret resources. User metadata can be stored in the annotations of the resource. + +```sh +kubectl apply -f - < **Note:** It may take a couple of minutes for the RateLimitPolicy to be applied depending on your cluster. + +Verify the rate limiting works by sending requests as Alice and Bob. + +Up to 5 successful (`200 OK`) requests every 10 seconds allowed for Alice, then `429 Too Many Requests`: + +```sh +while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMALICE' -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy | grep -E --color "\b(429)\b|$"; sleep 1; done +``` + +Up to 2 successful (`200 OK`) requests every 10 seconds allowed for Bob, then `429 Too Many Requests`: + +```sh +while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMBOB' -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy | grep -E --color "\b(429)\b|$"; sleep 1; done +``` + +## Cleanup + +```sh +make local-cleanup +``` diff --git a/doc/user-guides/simple-rl-for-app-developers.md b/doc/user-guides/ratelimiting/simple-rl-for-app-developers.md similarity index 79% rename from doc/user-guides/simple-rl-for-app-developers.md rename to doc/user-guides/ratelimiting/simple-rl-for-app-developers.md index 3b0889bed..fc4ec63c2 100644 --- a/doc/user-guides/simple-rl-for-app-developers.md +++ b/doc/user-guides/ratelimiting/simple-rl-for-app-developers.md @@ -1,49 +1,19 @@ -# Simple Rate Limiting for Application Developers +# Simple Rate Limiting for Application developers + +For more info on the different personas see [Gateway API](https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#key-roles-and-personas) -This user guide walks you through an example of how to configure rate limiting for an endpoint of an application using Kuadrant. -
+This user guide walks you through an example of how to configure rate limiting for an endpoint of an application using Kuadrant. In this guide, we will rate limit a sample REST API called **Toy Store**. In reality, this API is just an echo service that echoes back to the user whatever attributes it gets in the request. The API listens to requests at the hostname `api.toystore.com`, where it exposes the endpoints `GET /toys*` and `POST /toys`, respectively, to mimic operations of reading and writing toy records. We will rate limit the `POST /toys` endpoint to a maximum of 5rp10s ("5 requests every 10 seconds"). -
- -## Run the steps ① → ③ - -### ① Setup - -This step uses tooling from the Kuadrant Operator component to create a containerized Kubernetes server locally using [Kind](https://kind.sigs.k8s.io), -where it installs Istio, Kubernetes Gateway API and Kuadrant itself. - -> **Note:** In production environment, these steps are usually performed by a cluster operator with administrator privileges over the Kubernetes cluster. - -Clone the project: - -```sh -git clone https://github.com/Kuadrant/kuadrant-operator && cd kuadrant-operator -``` - -Setup the environment: +### Setup the environment -```sh -make local-setup -``` +Follow this [setup doc](https://github.com/Kuadrant/kuadrant-operator/blob/main/doc/install/install-make-target.md) to set up your environment before continuing with this doc. -Request an instance of Kuadrant: - -```sh -kubectl -n kuadrant-system apply -f - < kubectl port-forward -n gateway-system service/kuadrant-ingressgateway-istio 9080:80 >/dev/null 2>&1 & > export GATEWAY_URL=localhost:9080 > ``` +> > ```sh > curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/toys -i > # HTTP/1.1 200 OK > ``` -### ③ Enforce rate limiting on requests to the Toy Store API +### Enforce rate limiting on requests to the Toy Store API Create a Kuadrant `RateLimitPolicy` to configure rate limiting: @@ -130,6 +101,7 @@ spec: group: gateway.networking.k8s.io kind: HTTPRoute name: toystore + sectionName: rule-2 limits: "create-toy": rates: @@ -142,8 +114,6 @@ EOF > **Note:** It may take a couple of minutes for the RateLimitPolicy to be applied depending on your cluster. -
- Verify the rate limiting works by sending requests in a loop. Up to 5 successful (`200 OK`) requests every 10 seconds to `POST /toys`, then `429 Too Many Requests`: diff --git a/doc/user-guides/gateway-tls.md b/doc/user-guides/tls/gateway-tls.md similarity index 99% rename from doc/user-guides/gateway-tls.md rename to doc/user-guides/tls/gateway-tls.md index da673e930..e6952f0ce 100644 --- a/doc/user-guides/gateway-tls.md +++ b/doc/user-guides/tls/gateway-tls.md @@ -2,8 +2,6 @@ This user guide walks you through an example of how to configure TLS for all routes attached to an ingress gateway. -
- ## Requisites - [Docker](https://docker.io) @@ -26,6 +24,7 @@ make local-setup ``` Create a namespace: + ```shell kubectl create namespace my-gateways ``` @@ -33,6 +32,7 @@ kubectl create namespace my-gateways ### Create an ingress gateway Create a gateway: + ```sh kubectl -n my-gateways apply -f - < Host: api.toystore.local > user-agent: curl/7.85.0 > accept: */* -> +> * TLSv1.2 (IN), TLS header, Supplemental data (23): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): @@ -232,8 +253,8 @@ Response: * Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)! * TLSv1.2 (OUT), TLS header, Supplemental data (23): * TLSv1.2 (IN), TLS header, Supplemental data (23): -< HTTP/2 200 -HTTP/2 200 +< HTTP/2 200 +HTTP/2 200 < content-type: application/json content-type: application/json < server: istio-envoy @@ -245,7 +266,7 @@ content-length: 1658 < x-envoy-upstream-service-time: 1 x-envoy-upstream-service-time: 1 -< +< * Connection #0 to host api.toystore.local left intact ```