From 1d5ffa1457420291b6c9412ee76134231442baab Mon Sep 17 00:00:00 2001 From: airlockgithubci <67743769+airlockgithubci@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:44:52 +0200 Subject: [PATCH] CHG: Sync Artifacts - 4.4.0 --- README.md | 33 +- .../airlock-microgateway-cni/Chart.yaml | 6 +- .../charts/airlock-microgateway-cni/README.md | 26 +- .../airlock-microgateway-cni/values.yaml | 4 +- deploy/charts/airlock-microgateway/Chart.yaml | 6 +- deploy/charts/airlock-microgateway/README.md | 38 +- ...cesscontrols.microgateway.airlock.com.yaml | 385 ++++- ...ntsecurities.microgateway.airlock.com.yaml | 4 +- ...ritypolicies.microgateway.airlock.com.yaml | 476 ++++++ .../denyrules.microgateway.airlock.com.yaml | 16 +- ...nvoyclusters.microgateway.airlock.com.yaml | 4 +- ...nfigurations.microgateway.airlock.com.yaml | 4 +- ...yhttpfilters.microgateway.airlock.com.yaml | 4 +- .../graphqls.microgateway.airlock.com.yaml | 4 +- ...aderrewrites.microgateway.airlock.com.yaml | 1328 ++++++++++++++++- ...propagations.microgateway.airlock.com.yaml | 51 +- .../crds/jwks.microgateway.airlock.com.yaml | 294 ++++ .../crds/kustomization.yaml | 2 + .../crds/limits.microgateway.airlock.com.yaml | 4 +- ...idcproviders.microgateway.airlock.com.yaml | 67 +- ...lyingparties.microgateway.airlock.com.yaml | 47 +- .../openapis.microgateway.airlock.com.yaml | 4 +- .../parsers.microgateway.airlock.com.yaml | 4 +- ...disproviders.microgateway.airlock.com.yaml | 77 +- ...ionhandlings.microgateway.airlock.com.yaml | 34 +- ...ecargateways.microgateway.airlock.com.yaml | 4 +- .../telemetries.microgateway.airlock.com.yaml | 4 +- .../dashboards/blockLogs.json | 109 +- .../dashboards/blockMetrics.json | 41 +- .../dashboards/headerLogs.json | 378 +++++ .../dashboards/license.json | 596 +++++++- .../dashboards/logOnlyLogs.json | 382 +++++ .../dashboards/logOnlyMetrics.json | 621 ++++++++ .../dashboards/overview.json | 20 +- .../airlock-microgateway/templates/NOTES.txt | 22 +- .../templates/operator/_rbac.gen.tpl | 149 +- .../templates/operator/_webhooks.gen.tpl | 60 + .../templates/operator/configmap.yaml | 15 +- .../templates/tests/test-install.yaml | 4 +- .../tests/notes_test.yaml | 28 + .../tests/operator/dashboard_test.yaml | 120 +- .../airlock-microgateway/values.schema.json | 36 +- .../charts/airlock-microgateway/values.yaml | 40 +- examples/README.md | 4 +- examples/configurations/basic/README.md | 43 - .../configurations/basic/kustomization.yaml | 6 - .../configurations/basic/sidecargateway.yaml | 10 - examples/configurations/policy/README.md | 56 - .../policy/allowed/denyrules-1.yaml | 11 - .../policy/allowed/denyrules-2.yaml | 10 - .../policy/allowed/kustomization.yaml | 6 - .../policy/denied/denyrules-1.yaml | 11 - .../policy/denied/denyrules-2.yaml | 11 - .../policy/denied/kustomization.yaml | 6 - .../configurations/policy/kustomization.yaml | 5 - .../configurations/policy/kyverno-policy.yaml | 62 - examples/configurations/templating/README.md | 17 - .../templating/kustomization.yaml | 79 - .../templating/templates/contentsecurity.yaml | 10 - .../templating/templates/denyrules.yaml | 10 - .../templating/templates/headerrewrites.yaml | 83 -- .../templating/templates/kustomization.yaml | 13 - .../templating/templates/sidecargateway.yaml | 15 - .../gateway-api/conformance/conformance.md | 53 + .../manifests/conformance-report.yaml | 71 + examples/utilities/backends/README.md | 5 - .../nginx-protected/kustomization.yaml | 5 - examples/utilities/backends/nginx/common.conf | 15 - .../utilities/backends/nginx/default.conf | 7 - .../utilities/backends/nginx/deployment.yaml | 59 - .../backends/nginx/kustomization.yaml | 17 - examples/utilities/backends/nginx/nginx.conf | 64 - .../utilities/backends/nginx/service.yaml | 14 - examples/utilities/kyverno/.gitignore | 1 - examples/utilities/kyverno/README.md | 9 - examples/utilities/kyverno/values.yaml | 4 - 76 files changed, 5281 insertions(+), 1062 deletions(-) create mode 100644 deploy/charts/airlock-microgateway/crds/contentsecuritypolicies.microgateway.airlock.com.yaml create mode 100644 deploy/charts/airlock-microgateway/crds/jwks.microgateway.airlock.com.yaml create mode 100644 deploy/charts/airlock-microgateway/dashboards/headerLogs.json create mode 100644 deploy/charts/airlock-microgateway/dashboards/logOnlyLogs.json create mode 100644 deploy/charts/airlock-microgateway/dashboards/logOnlyMetrics.json delete mode 100644 examples/configurations/basic/README.md delete mode 100644 examples/configurations/basic/kustomization.yaml delete mode 100644 examples/configurations/basic/sidecargateway.yaml delete mode 100644 examples/configurations/policy/README.md delete mode 100644 examples/configurations/policy/allowed/denyrules-1.yaml delete mode 100644 examples/configurations/policy/allowed/denyrules-2.yaml delete mode 100644 examples/configurations/policy/allowed/kustomization.yaml delete mode 100644 examples/configurations/policy/denied/denyrules-1.yaml delete mode 100644 examples/configurations/policy/denied/denyrules-2.yaml delete mode 100644 examples/configurations/policy/denied/kustomization.yaml delete mode 100644 examples/configurations/policy/kustomization.yaml delete mode 100644 examples/configurations/policy/kyverno-policy.yaml delete mode 100644 examples/configurations/templating/README.md delete mode 100644 examples/configurations/templating/kustomization.yaml delete mode 100644 examples/configurations/templating/templates/contentsecurity.yaml delete mode 100644 examples/configurations/templating/templates/denyrules.yaml delete mode 100644 examples/configurations/templating/templates/headerrewrites.yaml delete mode 100644 examples/configurations/templating/templates/kustomization.yaml delete mode 100644 examples/configurations/templating/templates/sidecargateway.yaml create mode 100644 examples/gateway-api/conformance/conformance.md create mode 100644 examples/gateway-api/conformance/manifests/conformance-report.yaml delete mode 100644 examples/utilities/backends/README.md delete mode 100644 examples/utilities/backends/nginx-protected/kustomization.yaml delete mode 100644 examples/utilities/backends/nginx/common.conf delete mode 100644 examples/utilities/backends/nginx/default.conf delete mode 100644 examples/utilities/backends/nginx/deployment.yaml delete mode 100644 examples/utilities/backends/nginx/kustomization.yaml delete mode 100644 examples/utilities/backends/nginx/nginx.conf delete mode 100644 examples/utilities/backends/nginx/service.yaml delete mode 100644 examples/utilities/kyverno/.gitignore delete mode 100644 examples/utilities/kyverno/README.md delete mode 100644 examples/utilities/kyverno/values.yaml diff --git a/README.md b/README.md index 64672d8..67f09d7 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Modern application security is embedded in the development workflow and follows DevSecOps paradigms. Airlock Microgateway is the perfect fit for these requirements. It is a lightweight alternative to the Airlock Gateway appliance, optimized for Kubernetes environments. Airlock Microgateway protects your applications and microservices with the tried-and-tested Airlock security features against attacks, while also providing a high degree of scalability. ### Features -* Kubernetes native integration with its Operator, Custom Resource Definitions, hot-reload, automatic sidecar injection. +* Kubernetes native integration with sidecar injection and Gateway API support * Reverse proxy functionality with request routing rules, TLS termination and remote IP extraction * Using native Envoy HTTP filters like Lua scripting, RBAC, ext_authz, JWT authentication * Content security filters for protecting against known attacks (OWASP Top 10) @@ -61,41 +61,44 @@ For an easy start in non-production environments, you may deploy the same cert-m ### Deploy cert-manager ```bash helm repo add jetstack https://charts.jetstack.io -helm install cert-manager jetstack/cert-manager --version '1.15.1' -n cert-manager --create-namespace --set crds.enabled=true --wait +helm install cert-manager jetstack/cert-manager --version 'v1.16.1' -n cert-manager --create-namespace --set crds.enabled=true --wait ``` -## Deploy Airlock Microgateway CNI +## (Recommended) Deploy Airlock Microgateway CNI +> **Note**: Installing Airlock Microgateway CNI is required for data plane mode sidecar. +> +> See [documentation](https://docs.airlock.com/microgateway/latest/?topic=MGW-00000137) for more information about data plane modes. 1. Install the CNI Plugin with Helm. > **Note**: Certain environments such as OpenShift or GKE require non-default configurations when installing the CNI plugin. For the most common setups, values files are provided in the [chart folder](/deploy/charts/airlock-microgateway-cni). ```bash # Standard setup - helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' kubectl -n kube-system rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni ``` ```bash # GKE setup - helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' -f https://raw.githubusercontent.com/airlock/microgateway/4.3.4/deploy/charts/airlock-microgateway-cni/gke-values.yaml + helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' -f https://raw.githubusercontent.com/airlock/microgateway/4.4.0/deploy/charts/airlock-microgateway-cni/gke-values.yaml kubectl -n kube-system rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni ``` ```bash # OpenShift setup - helm install airlock-microgateway-cni -n openshift-operators oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' -f https://raw.githubusercontent.com/airlock/microgateway/4.3.4/deploy/charts/airlock-microgateway-cni/openshift-values.yaml + helm install airlock-microgateway-cni -n openshift-operators oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' -f https://raw.githubusercontent.com/airlock/microgateway/4.4.0/deploy/charts/airlock-microgateway-cni/openshift-values.yaml kubectl -n openshift-operators rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni ``` - **Important:** On OpenShift, all pods which should be protected by Airlock Microgateway must explicitly reference the Airlock Microgateway CNI NetworkAttachmentDefinition via the annotation `k8s.v1.cni.cncf.io/networks` (see [documentation](https://docs.airlock.com/microgateway/latest/#data/1658483168033.html) for details). + > **Important:** On OpenShift, all pods which should be protected by Airlock Microgateway must explicitly reference the Airlock Microgateway CNI NetworkAttachmentDefinition via the annotation `k8s.v1.cni.cncf.io/networks` (see [documentation](https://docs.airlock.com/microgateway/latest/#data/1658483168033.html) for details). 2. (Recommended) You can verify the correctness of the installation with `helm test`. ```bash # Standard and GKE setup - helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' helm test airlock-microgateway-cni -n kube-system --logs - helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' ``` ```bash # OpenShift setup - helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' helm test airlock-microgateway-cni -n openshift-operators --logs - helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' ``` Consult our [documentation](https://docs.airlock.com/microgateway/latest/#data/1699611533587.html) in case of any installation error. @@ -113,14 +116,14 @@ helm install cert-manager jetstack/cert-manager --version '1.15.1' -n cert-manag kubectl -n airlock-microgateway-system create secret generic airlock-microgateway-license --from-file=microgateway-license.txt # Install Operator (CRDs are included via the standard Helm 3 mechanism, i.e. Helm will handle initial installation but not upgrades) - helm install airlock-microgateway -n airlock-microgateway-system oci://quay.io/airlockcharts/microgateway --version '4.3.4' --wait + helm install airlock-microgateway -n airlock-microgateway-system oci://quay.io/airlockcharts/microgateway --version '4.4.0' --wait ``` 2. (Recommended) You can verify the correctness of the installation with `helm test`. ```bash - helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.3.4' + helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.4.0' helm test airlock-microgateway -n airlock-microgateway-system --logs - helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.3.4' + helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.4.0' ``` ### Upgrading CRDs @@ -128,7 +131,7 @@ helm install cert-manager jetstack/cert-manager --version '1.15.1' -n cert-manag The `helm install/upgrade` command currently does not support upgrading CRDs that already exist in the cluster. CRDs should instead be manually upgraded before upgrading the Operator itself via the following command: ```bash -kubectl apply -k https://github.com/airlock/microgateway/deploy/charts/airlock-microgateway/crds/?ref=4.3.4 --server-side --force-conflicts +kubectl apply -k https://github.com/airlock/microgateway/deploy/charts/airlock-microgateway/crds/?ref=4.4.0 --server-side --force-conflicts ``` **Note**: Certain GitOps solutions such as e.g. Argo CD or Flux CD have their own mechanisms for automatically upgrading CRDs included with Helm charts. diff --git a/deploy/charts/airlock-microgateway-cni/Chart.yaml b/deploy/charts/airlock-microgateway-cni/Chart.yaml index 9158d1f..07ebf6e 100644 --- a/deploy/charts/airlock-microgateway-cni/Chart.yaml +++ b/deploy/charts/airlock-microgateway-cni/Chart.yaml @@ -3,14 +3,14 @@ name: microgateway-cni description: A Helm chart for deploying the Airlock Microgateway CNI plugin type: application home: https://www.airlock.com/en/microgateway -version: "4.3.4" -appVersion: "4.3.4" +version: "4.4.0" +appVersion: "4.4.0" annotations: charts.openshift.io/name: Airlock Microgateway CNI artifacthub.io/category: security artifacthub.io/links: | - name: Airlock Microgateway Documentation - url: https://docs.airlock.com/microgateway/4.3/ + url: https://docs.airlock.com/microgateway/4.4/ - name: Airlock Microgateway Labs url: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=artifacthub.io - name: Airlock Microgateway Forum diff --git a/deploy/charts/airlock-microgateway-cni/README.md b/deploy/charts/airlock-microgateway-cni/README.md index 1559e00..f72f069 100644 --- a/deploy/charts/airlock-microgateway-cni/README.md +++ b/deploy/charts/airlock-microgateway-cni/README.md @@ -1,6 +1,6 @@ # Airlock Microgateway CNI -![Version: 4.3.4](https://img.shields.io/badge/Version-4.3.4-informational?style=flat-square) ![AppVersion: 4.3.4](https://img.shields.io/badge/AppVersion-4.3.4-informational?style=flat-square) +![Version: 4.4.0](https://img.shields.io/badge/Version-4.4.0-informational?style=flat-square) ![AppVersion: 4.4.0](https://img.shields.io/badge/AppVersion-4.4.0-informational?style=flat-square) *Airlock Microgateway is a Kubernetes native WAAP (Web Application and API Protection) solution to protect microservices.* @@ -13,10 +13,10 @@ Modern application security is embedded in the development workflow and follows DevSecOps paradigms. Airlock Microgateway is the perfect fit for these requirements. It is a lightweight alternative to the Airlock Gateway appliance, optimized for Kubernetes environments. Airlock Microgateway protects your applications and microservices with the tried-and-tested Airlock security features against attacks, while also providing a high degree of scalability. -__This Helm chart is part of Airlock Microgateway. See our [GitHub repo](https://github.com/airlock/microgateway/tree/4.3.4).__ +__This Helm chart is part of Airlock Microgateway. See our [GitHub repo](https://github.com/airlock/microgateway/tree/4.4.0).__ ### Features -* Kubernetes native integration with its Operator, Custom Resource Definitions, hot-reload, automatic sidecar injection. +* Kubernetes native integration with sidecar injection and Gateway API support * Reverse proxy functionality with request routing rules, TLS termination and remote IP extraction * Using native Envoy HTTP filters like Lua scripting, RBAC, ext_authz, JWT authentication * Content security filters for protecting against known attacks (OWASP Top 10) @@ -47,33 +47,33 @@ The instructions below provide a quick start guide. Detailed information are pro > **Note**: Certain environments such as OpenShift or GKE require non-default configurations when installing the CNI plugin. For the most common setups, values files are provided in the [chart folder](/deploy/charts/airlock-microgateway-cni). ```bash # Standard setup - helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' kubectl -n kube-system rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni ``` ```bash # GKE setup - helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' -f https://raw.githubusercontent.com/airlock/microgateway/4.3.4/deploy/charts/airlock-microgateway-cni/gke-values.yaml + helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' -f https://raw.githubusercontent.com/airlock/microgateway/4.4.0/deploy/charts/airlock-microgateway-cni/gke-values.yaml kubectl -n kube-system rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni ``` ```bash # OpenShift setup - helm install airlock-microgateway-cni -n openshift-operators oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' -f https://raw.githubusercontent.com/airlock/microgateway/4.3.4/deploy/charts/airlock-microgateway-cni/openshift-values.yaml + helm install airlock-microgateway-cni -n openshift-operators oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' -f https://raw.githubusercontent.com/airlock/microgateway/4.4.0/deploy/charts/airlock-microgateway-cni/openshift-values.yaml kubectl -n openshift-operators rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni ``` - **Important:** On OpenShift, all pods which should be protected by Airlock Microgateway must explicitly reference the Airlock Microgateway CNI NetworkAttachmentDefinition via the annotation `k8s.v1.cni.cncf.io/networks` (see [documentation](https://docs.airlock.com/microgateway/latest/#data/1658483168033.html) for details). + > **Important:** On OpenShift, all pods which should be protected by Airlock Microgateway must explicitly reference the Airlock Microgateway CNI NetworkAttachmentDefinition via the annotation `k8s.v1.cni.cncf.io/networks` (see [documentation](https://docs.airlock.com/microgateway/latest/#data/1658483168033.html) for details). 2. (Recommended) You can verify the correctness of the installation with `helm test`. ```bash # Standard and GKE setup - helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' helm test airlock-microgateway-cni -n kube-system --logs - helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' ``` ```bash # OpenShift setup - helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' helm test airlock-microgateway-cni -n openshift-operators --logs - helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.4' + helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.4.0' ``` Consult our [documentation](https://docs.airlock.com/microgateway/latest/#data/1699611533587.html) in case of any installation error. @@ -98,10 +98,10 @@ For the community edition, check our **[Airlock community forum](https://forum.a | config.installMode | string | `"chained"` | Whether to install the CNI plugin as a `chained` plugin (default, required with most interface CNI providers), as a `standalone` plugin (required for use with Multus CNI, e.g. on OpenShift) or in `manual` mode, where no CNI network configuration is written. | | config.logLevel | string | `"info"` | Log level for the CNI installer and plugin. | | fullnameOverride | string | `""` | Allows overriding the name to use as full name of resources. | -| image.digest | string | `"sha256:1e01310b3ad8566e9b39ee539ed5c959049aadda1a18c1a534e96d8865e20172"` | SHA256 image digest to pull (in the format "sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a"). Overrides tag when specified. | +| image.digest | string | `"sha256:e9d711dfe75d515ad8bc5ba5e668e7a26c063bd6a291305aac458c2cbd3945f2"` | SHA256 image digest to pull (in the format "sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a"). Overrides tag when specified. | | image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | | image.repository | string | `"quay.io/airlock/microgateway-cni"` | Image repository from which to pull the Airlock Microgateway CNI image. | -| image.tag | string | `"4.3.4"` | Image tag to pull. | +| image.tag | string | `"4.4.0"` | Image tag to pull. | | imagePullSecrets | list | `[]` | ImagePullSecrets to use when pulling images. | | multusNetworkAttachmentDefinition.create | bool | `false` | Whether a NetworkAttachmentDefinition CR should be created, which can be used for applying the CNI plugin to Pods. | | multusNetworkAttachmentDefinition.namespace | string | `"default"` | Namespace in which the NetworkAttachmentDefinition is deployed. Note: If namespace is set to a custom value, referencing the created NetworkAttachmentDefinition from other namespaces may not work if Multus namespace isolation is enabled. https://github.com/k8snetworkplumbingwg/multus-cni/blob/v4.0.2/docs/configuration.md#namespace-isolation | diff --git a/deploy/charts/airlock-microgateway-cni/values.yaml b/deploy/charts/airlock-microgateway-cni/values.yaml index 63ef360..1b6d8d3 100644 --- a/deploy/charts/airlock-microgateway-cni/values.yaml +++ b/deploy/charts/airlock-microgateway-cni/values.yaml @@ -15,10 +15,10 @@ image: # -- Image repository from which to pull the Airlock Microgateway CNI image. repository: "quay.io/airlock/microgateway-cni" # -- Image tag to pull. - tag: "4.3.4" + tag: "4.4.0" # -- SHA256 image digest to pull (in the format "sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a"). # Overrides tag when specified. - digest: "sha256:1e01310b3ad8566e9b39ee539ed5c959049aadda1a18c1a534e96d8865e20172" + digest: "sha256:e9d711dfe75d515ad8bc5ba5e668e7a26c063bd6a291305aac458c2cbd3945f2" # -- Pull policy for this image. pullPolicy: IfNotPresent # -- Annotations to add to all Pods. diff --git a/deploy/charts/airlock-microgateway/Chart.yaml b/deploy/charts/airlock-microgateway/Chart.yaml index a558ffb..bce27f7 100644 --- a/deploy/charts/airlock-microgateway/Chart.yaml +++ b/deploy/charts/airlock-microgateway/Chart.yaml @@ -3,14 +3,14 @@ name: microgateway description: A Helm chart for deploying the Airlock Microgateway type: application home: https://www.airlock.com/en/microgateway -version: "4.3.4" -appVersion: "4.3.4" +version: "4.4.0" +appVersion: "4.4.0" annotations: charts.openshift.io/name: Airlock Microgateway artifacthub.io/category: security artifacthub.io/links: | - name: Airlock Microgateway Documentation - url: https://docs.airlock.com/microgateway/4.3/ + url: https://docs.airlock.com/microgateway/4.4/ - name: Airlock Microgateway Labs url: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=artifacthub.io - name: Airlock Microgateway Forum diff --git a/deploy/charts/airlock-microgateway/README.md b/deploy/charts/airlock-microgateway/README.md index 5028932..b6f66cd 100644 --- a/deploy/charts/airlock-microgateway/README.md +++ b/deploy/charts/airlock-microgateway/README.md @@ -1,6 +1,6 @@ # Airlock Microgateway -![Version: 4.3.4](https://img.shields.io/badge/Version-4.3.4-informational?style=flat-square) ![AppVersion: 4.3.4](https://img.shields.io/badge/AppVersion-4.3.4-informational?style=flat-square) +![Version: 4.4.0](https://img.shields.io/badge/Version-4.4.0-informational?style=flat-square) ![AppVersion: 4.4.0](https://img.shields.io/badge/AppVersion-4.4.0-informational?style=flat-square) *Airlock Microgateway is a Kubernetes native WAAP (Web Application and API Protection) solution to protect microservices.* @@ -13,10 +13,10 @@ Modern application security is embedded in the development workflow and follows DevSecOps paradigms. Airlock Microgateway is the perfect fit for these requirements. It is a lightweight alternative to the Airlock Gateway appliance, optimized for Kubernetes environments. Airlock Microgateway protects your applications and microservices with the tried-and-tested Airlock security features against attacks, while also providing a high degree of scalability. -__This Helm chart is part of Airlock Microgateway. See our [GitHub repo](https://github.com/airlock/microgateway/tree/4.3.4).__ +__This Helm chart is part of Airlock Microgateway. See our [GitHub repo](https://github.com/airlock/microgateway/tree/4.4.0).__ ### Features -* Kubernetes native integration with its Operator, Custom Resource Definitions, hot-reload, automatic sidecar injection. +* Kubernetes native integration with sidecar injection and Gateway API support * Reverse proxy functionality with request routing rules, TLS termination and remote IP extraction * Using native Envoy HTTP filters like Lua scripting, RBAC, ext_authz, JWT authentication * Content security filters for protecting against known attacks (OWASP Top 10) @@ -40,7 +40,7 @@ Check the official documentation at **[docs.airlock.com](https://docs.airlock.co The instructions below provide a quick start guide. Detailed information are provided in the **[manual](https://docs.airlock.com/microgateway/latest/)**. ## Prerequisites -* [Airlock Microgateway CNI](https://artifacthub.io/packages/helm/airlock-microgateway-cni/microgateway-cni) +* (Recommended) [Airlock Microgateway CNI](https://artifacthub.io/packages/helm/airlock-microgateway-cni/microgateway-cni) (Required for [data plane mode sidecar](https://docs.airlock.com/microgateway/latest/?topic=MGW-00000137)) * [Airlock Microgateway License](#obtain-airlock-microgateway-license) * [cert-manager](https://cert-manager.io/) * [helm](https://helm.sh/docs/intro/install/) (>= v3.8.0) @@ -57,7 +57,7 @@ For an easy start in non-production environments, you may deploy the same cert-m ### Deploy cert-manager ```bash helm repo add jetstack https://charts.jetstack.io -helm install cert-manager jetstack/cert-manager --version '1.15.1' -n cert-manager --create-namespace --set crds.enabled=true --wait +helm install cert-manager jetstack/cert-manager --version 'v1.16.1' -n cert-manager --create-namespace --set crds.enabled=true --wait ``` ## Deploy Airlock Microgateway Operator @@ -73,14 +73,14 @@ helm install cert-manager jetstack/cert-manager --version '1.15.1' -n cert-manag kubectl -n airlock-microgateway-system create secret generic airlock-microgateway-license --from-file=microgateway-license.txt # Install Operator (CRDs are included via the standard Helm 3 mechanism, i.e. Helm will handle initial installation but not upgrades) - helm install airlock-microgateway -n airlock-microgateway-system oci://quay.io/airlockcharts/microgateway --version '4.3.4' --wait + helm install airlock-microgateway -n airlock-microgateway-system oci://quay.io/airlockcharts/microgateway --version '4.4.0' --wait ``` 2. (Recommended) You can verify the correctness of the installation with `helm test`. ```bash - helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.3.4' + helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.4.0' helm test airlock-microgateway -n airlock-microgateway-system --logs - helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.3.4' + helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.4.0' ``` ### Upgrading CRDs @@ -88,7 +88,7 @@ helm install cert-manager jetstack/cert-manager --version '1.15.1' -n cert-manag The `helm install/upgrade` command currently does not support upgrading CRDs that already exist in the cluster. CRDs should instead be manually upgraded before upgrading the Operator itself via the following command: ```bash -kubectl apply -k https://github.com/airlock/microgateway/deploy/charts/airlock-microgateway/crds/?ref=4.3.4 --server-side --force-conflicts +kubectl apply -k https://github.com/airlock/microgateway/deploy/charts/airlock-microgateway/crds/?ref=4.4.0 --server-side --force-conflicts ``` **Note**: Certain GitOps solutions such as e.g. Argo CD or Flux CD have their own mechanisms for automatically upgrading CRDs included with Helm charts. @@ -114,12 +114,15 @@ For the community edition, check our **[Airlock community forum](https://forum.a | dashboards.create | bool | `false` | Whether to create any ConfigMaps containing Grafana dashboards to import. | | dashboards.instances.blockLogs.create | bool | `true` | Whether to create the block logs dashboard. | | dashboards.instances.blockMetrics.create | bool | `true` | Whether to create the block metrics dashboard. | +| dashboards.instances.headerLogs.create | bool | `true` | Whether to create the header rewrite logs dashboard. | | dashboards.instances.license.create | bool | `true` | Whether to create the license dashboard. | +| dashboards.instances.logOnlyLogs.create | bool | `true` | Whether to create the log only logs dashboard. | +| dashboards.instances.logOnlyMetrics.create | bool | `true` | Whether to create the log only metrics dashboard | | dashboards.instances.overview.create | bool | `true` | Whether to create the overview dashboard. | -| engine.image.digest | string | `"sha256:91e05c509bed3b51ff4888d7475980d56cbc85db121aa766d1bde413204f9070"` | SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). Overrides tag when specified. | +| engine.image.digest | string | `"sha256:c29adf07e7536b72447ea694d0e19fe19235306c26d412a9abc43e4dd99b84c8"` | SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). Overrides tag when specified. | | engine.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | | engine.image.repository | string | `"quay.io/airlock/microgateway-engine"` | Image repository from which to pull the Airlock Microgateway Engine image. | -| engine.image.tag | string | `"4.3.4"` | Image tag to pull. | +| engine.image.tag | string | `"4.4.0"` | Image tag to pull. | | engine.resources | object | `{}` | Resource restrictions to apply to the Airlock Microgateway Engine container. | | engine.sidecar.podMonitor.create | bool | `false` | Whether to create a PodMonitor resource for monitoring. | | engine.sidecar.podMonitor.labels | object | `{}` | Labels to add to the PodMonitor. | @@ -127,16 +130,19 @@ For the community edition, check our **[Airlock community forum](https://forum.a | imagePullSecrets | list | `[]` | ImagePullSecrets to use when pulling images. | | license.secretName | string | `"airlock-microgateway-license"` | Name of the secret containing the "microgateway-license.txt" key. | | nameOverride | string | `""` | Allows overriding the name to use instead of "microgateway". | -| networkValidator.image.digest | string | `"sha256:7a73d4b82a2d4165bbc5efa55de4fee9d43f2b1c1edb3505cdc8afd1361bad9b"` | SHA256 image digest to pull (in the format "sha256:7a73d4b82a2d4165bbc5efa55de4fee9d43f2b1c1edb3505cdc8afd1361bad9b"). Overrides tag when specified. | +| networkValidator.image.digest | string | `"sha256:05585644690678ae6453ab12e3a5f899e7be5ab70f56c6bf1c4484d3b53587d2"` | SHA256 image digest to pull (in the format "sha256:05585644690678ae6453ab12e3a5f899e7be5ab70f56c6bf1c4484d3b53587d2"). Overrides tag when specified. | | networkValidator.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | | networkValidator.image.repository | string | `"cgr.dev/chainguard/netcat"` | Image repository from which to pull the netcat image for the Airlock Microgateway Network Validator init-container. | | networkValidator.image.tag | string | `""` | Image tag to pull. | +| networkValidator.resources | object | `{"limits":{"cpu":"25m","memory":"12Mi"},"requests":{"cpu":"5m","memory":"1Mi"}}` | Resource restrictions to apply to the Airlock Microgateway Network Validator init-container. | | operator.affinity | object | `{}` | Custom affinity to apply to the operator Deployment. Used to influence the scheduling. | | operator.config.logLevel | string | `"info"` | Operator application log level. | -| operator.image.digest | string | `"sha256:6819c78d5570de66edce6c13964c6e1b4cc4746d0c0bc6f4975cd38e324828c0"` | SHA256 image digest to pull (in the format "sha256:c79ee3f85862fb386e9dd62b901b607161d27807f512d7fbdece05e9ee3d7c63"). Overrides tag when specified. | +| operator.gatewayAPI.controllerName | string | `"microgateway.airlock.com/gatewayclass-controller"` | Controller name referred in the GatewayClasses managed by this operator. The value must be a path prefixed by the domain `microgateway.airlock.com`. | +| operator.gatewayAPI.enabled | bool | `false` | Whether to enable the Kubernetes Gateway API related controllers. Requires that the gateway.networking.k8s.io/v1 resources are installed on the cluster. | +| operator.image.digest | string | `"sha256:80cbae58ad9badd9395fa09a7b0576561821121b8353146bbd6efa2240ab5d97"` | SHA256 image digest to pull (in the format "sha256:c79ee3f85862fb386e9dd62b901b607161d27807f512d7fbdece05e9ee3d7c63"). Overrides tag when specified. | | operator.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | | operator.image.repository | string | `"quay.io/airlock/microgateway-operator"` | Image repository from which to pull the Airlock Microgateway Operator image. | -| operator.image.tag | string | `"4.3.4"` | Image tag to pull. | +| operator.image.tag | string | `"4.4.0"` | Image tag to pull. | | operator.nodeSelector | object | `{}` | Custom nodeSelector to apply to the operator Deployment in order to constrain its Pods to certain nodes. | | operator.podAnnotations | object | `{}` | Annotations to add to all Pods. | | operator.podLabels | object | `{}` | Labels to add to all Pods. | @@ -154,10 +160,10 @@ For the community edition, check our **[Airlock community forum](https://forum.a | operator.updateStrategy | object | `{"type":"RollingUpdate"}` | Specifies the operator update strategy. | | operator.watchNamespaceSelector | object | `{}` | Allows to dynamically select watch namespaces of the operator and the scope of the webhooks based on a Namespace label selector. It is able to detect and reconcile resources in all namespaces that match the label selector automatically, even for new namespaces, without restarting the operator. This facilitates a dynamic `MultiNamespace` installation mode, but still requires cluster-scoped permissions (i.e., ClusterRoles and ClusterRoleBindings). An `AllNamespaces` installation or the usage of the `watchNamespaces` requires the `watchNamespaceSelector` to be empty. Please note that this feature requires a Premium license. | | operator.watchNamespaces | list | `[]` | Allows to restrict the operator to specific namespaces, depending on your needs. For a `OwnNamespace` or `SingleNamespace` installation the list may only contain one namespace (e.g., `watchNamespaces: ["airlock-microgateway-system"]`). In case of the `OwnNamespace` installation mode the specified namespace should be equal to the installation namespace. For a static `MultiNamespace` installation, the complete list of namespaces must be provided in the `watchNamespaces`. An `AllNamespaces` installation or the usage of the `watchNamespaceSelector` requires the `watchNamespaces` to be empty. Regardless of the installation modes supported by `watchNamespaces`, RBAC is created only namespace-scoped (using Roles and RoleBindings) in the respective namespaces. Please note that this feature requires a Premium license. | -| sessionAgent.image.digest | string | `"sha256:df4e50d0929cb4c5e4486452979b59ec17f5e49a1516b685acd3a1ab0ddb3cf4"` | SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). Overrides tag when specified. | +| sessionAgent.image.digest | string | `"sha256:fbb90f2a52bb1b19cca6c5c133e80331153c019ec905db052c250fedbb09c3bc"` | SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). Overrides tag when specified. | | sessionAgent.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | | sessionAgent.image.repository | string | `"quay.io/airlock/microgateway-session-agent"` | Image repository from which to pull the Airlock Microgateway Session Agent image. | -| sessionAgent.image.tag | string | `"4.3.4"` | Image tag to pull. | +| sessionAgent.image.tag | string | `"4.4.0"` | Image tag to pull. | | sessionAgent.resources | object | `{}` | Resource restrictions to apply to the Airlock Microgateway Session Agent container. | | tests.enabled | bool | `false` | Whether additional resources required for running `helm test` should be created (e.g. Roles and ServiceAccounts). If set to false, `helm test` will not run any tests. | diff --git a/deploy/charts/airlock-microgateway/crds/accesscontrols.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/accesscontrols.microgateway.airlock.com.yaml index 9dc81f1..9e6c704 100644 --- a/deploy/charts/airlock-microgateway/crds/accesscontrols.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/accesscontrols.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: accesscontrols.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -48,7 +48,7 @@ spec: description: Specifies how the Airlock Microgateway Engine performs access control. properties: policies: - description: Policies configures access control policies. + description: Policies configures access control policies. The first matching policy (from top to bottom) applies. items: properties: authorization: @@ -74,6 +74,161 @@ spec: - oidcRelyingPartyRef type: object type: object + deny: + description: Deny specifies to deny access for all requests matching this policy. + type: object + requireAll: + description: RequireAll specifies conditions which must all be satisfied for the request to be authorized. + items: + properties: + oidc: + description: OIDC specifies a condition on the result of an OpenID Connect flow. + properties: + claim: + description: Claim specifies a condition on a JWT claim. + properties: + name: + description: Name of the claim. + minLength: 1 + type: string + value: + description: |- + Value of the claim. If not specified, only existence of the claim is checked (any value is allowed). + + Value matching is only supported if the data type of the claim is either primitive (`number`, `boolean`, `string`) or `array` of primitives. + In case of a non-string value, the match will be performed against the stringified value. + + If the claim has an unsupported data type (e.g. `object` or `null`), its value will never match. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + required: + - name + type: object + required: + - claim + type: object + required: + - oidc + type: object + minItems: 1 + type: array + requireAny: + description: RequireAny specifies conditions of which at least one must be satisfied for the request to be authorized. + items: + properties: + oidc: + description: OIDC specifies a condition on the result of an OpenID Connect flow. + properties: + claim: + description: Claim specifies a condition on a JWT claim. + properties: + name: + description: Name of the claim. + minLength: 1 + type: string + value: + description: |- + Value of the claim. If not specified, only existence of the claim is checked (any value is allowed). + + Value matching is only supported if the data type of the claim is either primitive (`number`, `boolean`, `string`) or `array` of primitives. + In case of a non-string value, the match will be performed against the stringified value. + + If the claim has an unsupported data type (e.g. `object` or `null`), its value will never match. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + required: + - name + type: object + required: + - claim + type: object + required: + - oidc + type: object + minItems: 1 + type: array type: object identityPropagation: description: IdentityPropagation configures how the authenticated user's identity is communicated to the protected application. @@ -107,10 +262,232 @@ spec: - actions - onFailure type: object + requestConditions: + description: |- + RequestConditions defines additional request properties which must be matched in order for this policy to apply. A policy without request conditions will always match. + + WARNING: There is currently a limitation that if `authentication.oidc` is configured for this policy, you must ensure that the request condition also matches logout requests and callback redirects from the OIDC Provider as configured in the OIDCRelyingParty (`pathMapping.logoutPath` / `pathMapping.redirectPath`). + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object required: - authorization type: object - maxItems: 1 minItems: 1 type: array required: diff --git a/deploy/charts/airlock-microgateway/crds/contentsecurities.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/contentsecurities.microgateway.airlock.com.yaml index e63a5b1..7fa6108 100644 --- a/deploy/charts/airlock-microgateway/crds/contentsecurities.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/contentsecurities.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: contentsecurities.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/contentsecuritypolicies.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/contentsecuritypolicies.microgateway.airlock.com.yaml new file mode 100644 index 0000000..be0e8cf --- /dev/null +++ b/deploy/charts/airlock-microgateway/crds/contentsecuritypolicies.microgateway.airlock.com.yaml @@ -0,0 +1,476 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.4.0 + gateway.networking.k8s.io/policy: direct + name: contentsecuritypolicies.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: ContentSecurityPolicy + listKind: ContentSecurityPolicyList + plural: contentsecuritypolicies + singular: contentsecuritypolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ContentSecurityPolicy is a Direct Attached Policy for the Kubernetes Gateway API. It specifies the options to secure an upstream web application with a Microgateway. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of ContentSecurityPolicy. + properties: + secured: + description: Secured enables WAF processing for the routes attached to this policy. + properties: + apiProtection: + description: |- + APIProtection defines the relevant configurations to protect APIs. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + graphQLRef: + description: |- + GraphQLRef selects the relevant GraphQL configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + openAPIRef: + description: |- + OpenAPIRef selects the relevant OpenAPI configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + filter: + description: |- + Filter defines the set of filters, e.g. Airlock Deny Rules, to be applied to incoming requests + to protect against various attack patterns. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + denyRulesRef: + description: |- + DenyRulesRef selects the relevant DenyRules configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + limitsRef: + description: |- + LimitsRef selects the relevant Limits configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + parserRef: + description: |- + ParserRef selects the relevant Parser configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + targetRefs: + description: |- + TargetRefs are the resources this policy is being attached to. Referenced resources must be in the same namespace as the policy. + Support: HTTPRoute. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-validations: + - message: 'TargetRef Kind must be: HTTPRoute' + rule: self.all(t, t.kind=='HTTPRoute') + - message: TargetRef Group must be gateway.networking.k8s.io. + rule: self.all(t, t.group=='gateway.networking.k8s.io') + unsecured: + description: |- + Unsecured disables all WAF functionality and therefore protection for the routes attached to this policy. + WARNING: Using this setting when the application is exposed to untrusted downstream traffic is highly discouraged. + type: object + required: + - targetRefs + type: object + status: + description: Status defines the state of the ContentSecurityPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with respect to the given Ancestor. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy/charts/airlock-microgateway/crds/denyrules.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/denyrules.microgateway.airlock.com.yaml index 7108ee5..ac120c8 100644 --- a/deploy/charts/airlock-microgateway/crds/denyrules.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/denyrules.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: denyrules.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -864,7 +864,9 @@ spec: TEMPLATE | UNIXCMD | WINCMD | - XSS + XSS | + SSRF | + BOT enum: - ENCODING - EXPLOIT @@ -883,6 +885,8 @@ spec: - UNIXCMD - WINCMD - XSS + - SSRF + - BOT type: string minItems: 1 type: array @@ -917,7 +921,9 @@ spec: TEMPLATE | UNIXCMD | WINCMD | - XSS + XSS | + SSRF | + BOT enum: - ENCODING - EXPLOIT @@ -936,6 +942,8 @@ spec: - UNIXCMD - WINCMD - XSS + - SSRF + - BOT type: string minItems: 1 type: array diff --git a/deploy/charts/airlock-microgateway/crds/envoyclusters.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/envoyclusters.microgateway.airlock.com.yaml index 35dda9f..5d82a25 100644 --- a/deploy/charts/airlock-microgateway/crds/envoyclusters.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/envoyclusters.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: envoyclusters.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/envoyconfigurations.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/envoyconfigurations.microgateway.airlock.com.yaml index c4f61f2..97c3a03 100644 --- a/deploy/charts/airlock-microgateway/crds/envoyconfigurations.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/envoyconfigurations.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: envoyconfigurations.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/envoyhttpfilters.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/envoyhttpfilters.microgateway.airlock.com.yaml index 538ff67..7df49ba 100644 --- a/deploy/charts/airlock-microgateway/crds/envoyhttpfilters.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/envoyhttpfilters.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: envoyhttpfilters.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/graphqls.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/graphqls.microgateway.airlock.com.yaml index 165abe0..215cbb6 100644 --- a/deploy/charts/airlock-microgateway/crds/graphqls.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/graphqls.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: graphqls.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/headerrewrites.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/headerrewrites.microgateway.airlock.com.yaml index 72a1067..c7c4f7f 100644 --- a/deploy/charts/airlock-microgateway/crds/headerrewrites.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/headerrewrites.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: headerrewrites.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -84,6 +84,226 @@ spec: description: Name describing the configured operation. minLength: 1 type: string + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this operation to be applied. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object required: - headers - name @@ -113,6 +333,10 @@ spec: default: true description: StandardHeaders defines whether the request headers which are forwarded to the upstream will be restricted to a set of common request headers. type: boolean + tracingHeaders: + default: false + description: TracingHeaders defines whether to allow common tracing headers to be forwarded to the upstream. + type: boolean type: object custom: description: Custom allows configuring additional upstream request headers. @@ -218,6 +442,226 @@ spec: description: Name describing the configured operation. Must be unique. minLength: 1 type: string + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this operation to be applied. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object required: - headers - name @@ -346,6 +790,226 @@ spec: description: Name describing the configured operation. Must be unique. minLength: 1 type: string + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this operation to be applied. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object required: - headers - name @@ -441,6 +1105,226 @@ spec: description: Name describing the configured operation. minLength: 1 type: string + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this operation to be applied. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object required: - headers - name @@ -575,6 +1459,226 @@ spec: description: Name describing the configured operation. Must be unique. minLength: 1 type: string + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this operation to be applied. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object required: - headers - name @@ -731,6 +1835,226 @@ spec: description: Name describing the configured remove operation. Must be unique. minLength: 1 type: string + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this operation to be applied. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object required: - headers - name diff --git a/deploy/charts/airlock-microgateway/crds/identitypropagations.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/identitypropagations.microgateway.airlock.com.yaml index 661e932..4a5df8e 100644 --- a/deploy/charts/airlock-microgateway/crds/identitypropagations.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/identitypropagations.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: identitypropagations.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -47,6 +47,48 @@ spec: spec: description: Specification of the desired identity propagation. properties: + bearerToken: + description: BearerToken configures identity propagation via an authorization header containing a bearer token. + properties: + source: + description: Source from which to extract the token. + properties: + metadata: + description: Metadata specifies to extract a value from an Envoy dynamic filter metadata key. + properties: + key: + description: Key specifies the metadata key from which to load the value, e.g. `some_payload.aud`. + minLength: 1 + type: string + namespace: + description: Namespace specifies the metadata namespace within which the lookup should be performed, e.g. `envoy.filters.http.jwt_authn`. + minLength: 1 + type: string + required: + - key + - namespace + type: object + oidc: + description: OIDC specifies to extract a value from the result of an OpenID Connect flow. + properties: + accessToken: + description: AccessToken specifies to extract the value from the OpenID Connect Access Token. + type: object + idToken: + description: IDToken specifies to extract the value from the OpenID Connect ID Token. + properties: + claim: + description: Claim selects the JWT claim from which to extract the value. + minLength: 1 + type: string + required: + - claim + type: object + type: object + type: object + required: + - source + type: object header: description: Header configures identity propagation via a request header. properties: @@ -78,6 +120,9 @@ spec: oidc: description: OIDC specifies to extract a value from the result of an OpenID Connect flow. properties: + accessToken: + description: AccessToken specifies to extract the value from the OpenID Connect Access Token. + type: object idToken: description: IDToken specifies to extract the value from the OpenID Connect ID Token. properties: @@ -88,8 +133,6 @@ spec: required: - claim type: object - required: - - idToken type: object type: object required: diff --git a/deploy/charts/airlock-microgateway/crds/jwks.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/jwks.microgateway.airlock.com.yaml new file mode 100644 index 0000000..4ea6213 --- /dev/null +++ b/deploy/charts/airlock-microgateway/crds/jwks.microgateway.airlock.com.yaml @@ -0,0 +1,294 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.4.0 + name: jwks.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: JWKS + listKind: JWKSList + plural: jwks + singular: jwks + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: JWKS provides a JSON Web Key Set. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the JWKS. + properties: + provider: + description: Provider configures the source from which to retrieve the JWKS. + properties: + local: + description: Local specifies to retrieve the JWKS from a local secret. + properties: + secretRef: + description: SecretRef selects the secret containing the JWKS under the key 'jwks.json'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + remote: + description: Remote specifies to retrieve the JWKS from a remote endpoint. + properties: + timeouts: + description: Timeouts specifies the timeouts when interacting with the Token endpoint. + properties: + connect: + default: 5s + description: Connect specifies the timeout for establishing a connection. + type: string + maxDuration: + default: 15s + description: MaxDuration specifies the response timeout. + type: string + type: object + tls: + description: TLS defines TLS settings. + properties: + certificateVerification: + description: CertificateVerification specifies how the certificate presented by the server is verified. + properties: + custom: + description: |- + Custom explicitly specifies how the server certificate should be verified. + Typical use cases include specifying a custom CA and SAN match when working with self-signed certificates or pinning a specific public key. + properties: + allowedSANs: + description: |- + AllowedSANs is a list of matchers to verify the Subject Alternative name. If specified, it will verify that the + Subject Alternative Name of the presented certificate matches one of the specified matchers. The matching uses “any” semantics, + that is to say, the SAN is verified if at least one matcher is matched. + AllowedSANs requires trustedCA to be set. + items: + description: |- + TLSValidationContextSANMatcher is a list of matchers to verify the Subject Alternative name. If specified, it will verify that the + Subject Alternative Name of the presented certificate matches one of the specified matchers. + properties: + matcher: + description: Matcher defines the string matcher for the SAN value. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + sanType: + description: SanType defines the type of SAN matcher. + enum: + - DNS + - Email + - URI + - IPAddress + type: string + required: + - matcher + - sanType + type: object + minItems: 1 + type: array + certificatePinning: + description: |- + CertificatePinning defines constraints the presented certificate must fulfill. + If more than one constraint is configured only one must be satisfied. + At least one of allowedSPKIs and allowedHashes must be set. + properties: + allowedHashes: + description: |- + AllowedHashes is a list of hex-encoded SHA-256 hashes. + If specified, it will verify that the SHA-256 of the DER-encoded presented certificate matches one of the specified values. + items: + type: string + minItems: 1 + type: array + allowedSPKIs: + description: |- + AllowedSPKIs is a list of base64-encoded SHA-256 hashes. + If specified, it will verify that the SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate matches one of the specified values. + items: + type: string + minItems: 1 + type: array + type: object + crl: + description: CRL defines the Certificate Revocation List (CRL) settings. + properties: + lists: + description: Lists defines the list of secretRefs containing Certificate Revocation Lists. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CRL's (in PEM format) under the key 'ca.crl'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + validationMode: + default: VerifyChain + description: ValidationMode defines whether only the leaf certificate or also the CA certs should be checked. + enum: + - VerifyLeafCertOnly + - VerifyChain + type: string + type: object + trustedCA: + description: TrustedCA defines which CA certificates are trusted. + properties: + certificates: + description: Certificates defines the list of secretRefs containing trusted CA certificates. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CA certificates under the key 'ca.crt'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + verificationDepth: + default: 1 + description: |- + VerificationDepth specifies the hops in the certificate chain at which validation is performed. + 1 means that either the leaf or the signing CA must be in the set of trusted certificates. + format: int32 + type: integer + required: + - certificates + type: object + type: object + disabled: + description: |- + Disabled specifies to trust any certificate without verification. + THIS IS INSECURE AND SHOULD ONLY BE USED FOR TESTING. + type: object + publicCAs: + description: PublicCAs specifies to only accept certificates with a SAN matching "uri" and which are signed by a CA which is either directly or indirectly trusted by any of the root CA certificates shipped with the Airlock Microgateway Engine's base image. + type: object + type: object + ciphers: + description: Ciphers defines a list of the supported TLS cipher suites. For details on cipher list refer to the envoy documentation on cipher_suites in common tls configuration. + items: + type: string + minItems: 1 + type: array + protocol: + description: Protocol defines the supported TLS protocol versions. + properties: + maximum: + description: Maximum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + minimum: + description: Minimum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + type: object + type: object + uri: + description: URI specifies the endpoint address. + format: uri + minLength: 1 + pattern: ^(http|https)://.*$ + type: string + required: + - uri + type: object + type: object + required: + - provider + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/deploy/charts/airlock-microgateway/crds/kustomization.yaml b/deploy/charts/airlock-microgateway/crds/kustomization.yaml index 1ce3147..5604dc5 100644 --- a/deploy/charts/airlock-microgateway/crds/kustomization.yaml +++ b/deploy/charts/airlock-microgateway/crds/kustomization.yaml @@ -3,6 +3,7 @@ kind: Kustomization resources: - accesscontrols.microgateway.airlock.com.yaml - contentsecurities.microgateway.airlock.com.yaml +- contentsecuritypolicies.microgateway.airlock.com.yaml - denyrules.microgateway.airlock.com.yaml - envoyclusters.microgateway.airlock.com.yaml - envoyconfigurations.microgateway.airlock.com.yaml @@ -10,6 +11,7 @@ resources: - graphqls.microgateway.airlock.com.yaml - headerrewrites.microgateway.airlock.com.yaml - identitypropagations.microgateway.airlock.com.yaml +- jwks.microgateway.airlock.com.yaml - limits.microgateway.airlock.com.yaml - oidcproviders.microgateway.airlock.com.yaml - oidcrelyingparties.microgateway.airlock.com.yaml diff --git a/deploy/charts/airlock-microgateway/crds/limits.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/limits.microgateway.airlock.com.yaml index a75813d..3f3cae2 100644 --- a/deploy/charts/airlock-microgateway/crds/limits.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/limits.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: limits.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/oidcproviders.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/oidcproviders.microgateway.airlock.com.yaml index 030bd15..a4b737d 100644 --- a/deploy/charts/airlock-microgateway/crds/oidcproviders.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/oidcproviders.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: oidcproviders.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -28,19 +28,7 @@ spec: description: |- OIDCProvider specifies an OpenID Provider (OP). - - {{% notice warning %}} The OIDC feature is currently in an experimental state. - - - We encourage you to try it out and give feedback, but be aware that we do not recommend using it in a production environment yet, as security has not yet been hardened. - In particular, the current implementation has the following limitations, which we intend to address in future Microgateway releases: - - The state parameter is guessable. - - Sessions are always shared across all Microgateway Engines using the same Redis instance. - I.e. if application A and B (with different SidecarGateways) have the same Redis instance configured in their SessionHandling CR, users which are logged into application A - may be able to access authenticated routes on application B, even if their OIDCRelyingParty configuration differs. - - - {{% /notice %}} + {{% notice info %}} The OIDC feature requires SessionHandling to be configured in the SidecarGateway. {{% /notice %}} properties: apiVersion: description: |- @@ -83,6 +71,18 @@ spec: token: description: Token configures the endpoint from which the access, ID and refresh tokens are obtained. properties: + timeouts: + description: Timeouts specifies the timeouts when interacting with the Token endpoint. + properties: + connect: + default: 5s + description: Connect specifies the timeout for establishing a connection. + type: string + maxDuration: + default: 15s + description: MaxDuration specifies the response timeout. + type: string + type: object tls: description: TLS defines TLS settings. properties: @@ -293,8 +293,45 @@ spec: - authorization - token type: object + issuer: + description: Issuer specifies the unique identifier of the OIDC Provider, which is used e.g. for signature verification. + format: uri + minLength: 1 + pattern: ^(http|https)://.*$ + type: string + tokenValidation: + description: TokenValidation configures token validation. + properties: + idToken: + description: IDToken configures validation for the OIDC ID Token. + properties: + signatureVerification: + description: SignatureVerification specifies how to verify the ID Token signature. + properties: + disabled: + description: Disabled specifies to skip verification of the JWT signature. Not recommended for production environments. + type: object + jwksRef: + description: JwksRef specifies the JWKS to use for verifying the JWT signature (usually provided by the OpenID Provider). + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + required: + - signatureVerification + type: object + required: + - idToken + type: object required: - endpoints + - issuer + - tokenValidation type: object type: object required: diff --git a/deploy/charts/airlock-microgateway/crds/oidcrelyingparties.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/oidcrelyingparties.microgateway.airlock.com.yaml index 7398b26..3c071bc 100644 --- a/deploy/charts/airlock-microgateway/crds/oidcrelyingparties.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/oidcrelyingparties.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: oidcrelyingparties.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -28,19 +28,6 @@ spec: description: |- OIDCRelyingParty specifies how the Airlock Microgateway Engine interacts with an OpenID Provider (OP). - - {{% notice warning %}} The OIDC feature is currently in an experimental state. - - - We encourage you to try it out and give feedback, but be aware that we do not recommend using it in a production environment yet, as security has not yet been hardened. - In particular, the current implementation has the following limitations, which we intend to address in future Microgateway releases: - - The state parameter is guessable. - - Sessions are always shared across all Microgateway Engines using the same Redis instance. - I.e. if application A and B (with different SidecarGateways) have the same Redis instance configured in their SessionHandling CR, users which are logged into application A - may be able to access authenticated routes on application B, even if their OIDCRelyingParty configuration differs. - - - {{% /notice %}} {{% notice info %}} The OIDC feature requires SessionHandling to be configured in the SidecarGateway. {{% /notice %}} properties: apiVersion: @@ -96,6 +83,10 @@ spec: required: - clientSecret type: object + flowTimeout: + default: 5m + description: FlowTimeout specifies the time window within which an initiated OIDC flow can be completed by the client. + type: string oidcProviderRef: description: OIDCProviderRef selects the OpenID Provider (OP) used to authenticate users. properties: @@ -110,7 +101,10 @@ spec: description: PathMapping configures the action matching. properties: logoutPath: - description: LogoutPath specifies which request paths should initiate a logout. + description: |- + LogoutPath specifies which request paths should initiate a logout. + + WARNING: If the AccessControl policy referencing this OIDCRelyingParty has a request condition, you must currently ensure that it also matches these logout requests. properties: matcher: description: StringMatcher defines the way to match a string. @@ -155,7 +149,10 @@ spec: - matcher type: object redirectPath: - description: RedirectPath specifies which request paths should be interpreted as a response from the authorization endpoint. + description: |- + RedirectPath specifies which request paths should be interpreted as a callback redirect from the authorization endpoint. + + WARNING: If the AccessControl policy referencing this OIDCRelyingParty has a request condition, you must currently ensure that it also matches these callback redirect requests. properties: matcher: description: StringMatcher defines the way to match a string. @@ -206,9 +203,23 @@ spec: redirectURI: description: |- RedirectURI configures the "redirect_uri" parameter included in the authorization request. - May contain envoy command operators, e.g. '%REQ(:x-forwarded-proto)%://%REQ(:authority)%/callback'. + May contain envoy command operators, e.g.: `%REQ(:x-forwarded-proto)%://%REQ(:authority)%/callback` + + WARNING: If the AccessControl policy referencing this OIDCRelyingParty has a request condition, you must currently + ensure that it also matches requests to this URI. minLength: 1 type: string + scopes: + description: |- + Scopes specifies the scopes to request during the OIDC flow. + The mandatory `openid` scope is implicitly added to the list if not already present. + Default: `['openid', 'profile']` + + Note: Different OIDCRelyingParties which use the same OIDC Provider and Client ID must request the same scopes for now. + items: + minLength: 1 + type: string + type: array required: - clientID - credentials diff --git a/deploy/charts/airlock-microgateway/crds/openapis.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/openapis.microgateway.airlock.com.yaml index b05f43e..f4b9bc2 100644 --- a/deploy/charts/airlock-microgateway/crds/openapis.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/openapis.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: openapis.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/parsers.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/parsers.microgateway.airlock.com.yaml index 15171f2..ab0a5f4 100644 --- a/deploy/charts/airlock-microgateway/crds/parsers.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/parsers.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: parsers.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/redisproviders.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/redisproviders.microgateway.airlock.com.yaml index 9acdf4d..44b70be 100644 --- a/deploy/charts/airlock-microgateway/crds/redisproviders.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/redisproviders.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: redisproviders.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -74,6 +74,63 @@ spec: mode: description: Mode configures the redis deployment mode. properties: + cluster: + description: Cluster specifies the Redis Cluster to connect to. + properties: + nodes: + description: Nodes specifies the Cluster nodes. + items: + properties: + host: + description: Host specifies the IP or hostname. + minLength: 1 + pattern: ^(\d{1,3}(\.\d{1,3}){3}|([0-9a-fA-F]{1,4}|:)+(:\d{1,3}(\.\d{1,3}){3})?|[a-z0-9\-]+(\.[a-z0-9\-]+)*)$ + type: string + port: + default: 6379 + description: Port specifies the port. + maximum: 65535 + minimum: 1 + type: integer + required: + - host + type: object + minItems: 1 + type: array + required: + - nodes + type: object + sentinel: + description: Sentinel specifies the Redis Sentinels to connect to. + properties: + masterName: + description: MasterName specifies the master name. + minLength: 1 + type: string + nodes: + description: Nodes specifies the Sentinel nodes. + items: + properties: + host: + description: Host specifies the IP or hostname. + minLength: 1 + pattern: ^(\d{1,3}(\.\d{1,3}){3}|([0-9a-fA-F]{1,4}|:)+(:\d{1,3}(\.\d{1,3}){3})?|[a-z0-9\-]+(\.[a-z0-9\-]+)*)$ + type: string + port: + default: 6379 + description: Port specifies the port. + maximum: 65535 + minimum: 1 + type: integer + required: + - host + type: object + minItems: 1 + type: array + required: + - masterName + - nodes + type: object standalone: description: Standalone specifies the standalone Redis instance to connect to. properties: @@ -148,6 +205,22 @@ spec: description: PublicCAs specifies to only accept certificates with a SAN matching the host and which are signed by a CA which is either directly or indirectly trusted by any of the root CA certificates shipped with the Airlock Microgateway Session Agent’s base image. type: object type: object + clientCertificate: + description: ClientCertificate configures client certificate authentication. If not specified, TLS-based client authentication is disabled. + properties: + secretRef: + description: SecretRef specifies the client certificate to use (secret of type kubernetes.io/tls). + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object type: object required: - mode diff --git a/deploy/charts/airlock-microgateway/crds/sessionhandlings.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/sessionhandlings.microgateway.airlock.com.yaml index bb4c0f9..4014275 100644 --- a/deploy/charts/airlock-microgateway/crds/sessionhandlings.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/sessionhandlings.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: sessionhandlings.microgateway.airlock.com spec: group: microgateway.airlock.com @@ -21,15 +21,7 @@ spec: - name: v1alpha1 schema: openAPIV3Schema: - description: |- - SessionHandling contains the configuration for session handling. - - - {{% notice warning %}} The Session Handling feature (required for OIDC) is currently in an experimental state. - - - We encourage you to try it out and give feedback, but be aware that we do not recommend using it in a production environment yet, as high-availability Redis configurations (e.g. Sentinel/Cluster) are not yet supported. - {{% /notice %}} + description: SessionHandling contains the configuration for session handling. properties: apiVersion: description: |- @@ -51,6 +43,14 @@ spec: spec: description: Specification of the desired session handling behavior. properties: + defaultTimeouts: + description: DefaultTimeouts specifies the session timeouts to apply when not provided by the authentication method. + properties: + lifetime: + default: 12h + description: Lifetime specifies the maximum duration a session can exist. + type: string + type: object persistence: description: Persistence configures where to store the session state. properties: @@ -67,6 +67,18 @@ spec: required: - redisProviderRef type: object + prefix: + description: |- + Prefix specifies the prefix under which the sessions should be stored in the persistence layer. + If not specified, an automatic prefix derived from the namespaced SessionHandling CR name is used, which ensures that sessions will always be isolated on Microgateways configured with different SessionHandling CRs, even if they share the same persistence backend. + + To allow session sharing between different Microgateway deployments, ensure that the prefix and persistence backend is the same across all corresponding SessionHandling CRs. + + Note: Session cookies are currently never shared across different fully qualified domain names (FQDNs) and authentication via different OIDC Relying Parties generates different session cookies. Clients will therefore only able to transparently reuse session cookies for connecting to different Microgateway deployments if those are a) exposed under the same FQDN and b) handle authentication via the same OIDC Relying Party. + maxLength: 64 + minLength: 1 + pattern: ^[a-zA-Z][a-zA-Z0-9_]*$ + type: string required: - persistence type: object diff --git a/deploy/charts/airlock-microgateway/crds/sidecargateways.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/sidecargateways.microgateway.airlock.com.yaml index 6847f73..d4de013 100644 --- a/deploy/charts/airlock-microgateway/crds/sidecargateways.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/sidecargateways.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: sidecargateways.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/crds/telemetries.microgateway.airlock.com.yaml b/deploy/charts/airlock-microgateway/crds/telemetries.microgateway.airlock.com.yaml index d1a8897..7dcfbc1 100644 --- a/deploy/charts/airlock-microgateway/crds/telemetries.microgateway.airlock.com.yaml +++ b/deploy/charts/airlock-microgateway/crds/telemetries.microgateway.airlock.com.yaml @@ -2,10 +2,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.4 labels: app.kubernetes.io/name: airlock-microgateway-operator - app.kubernetes.io/version: 4.3.4 + app.kubernetes.io/version: 4.4.0 name: telemetries.microgateway.airlock.com spec: group: microgateway.airlock.com diff --git a/deploy/charts/airlock-microgateway/dashboards/blockLogs.json b/deploy/charts/airlock-microgateway/dashboards/blockLogs.json index ef0ce6d..8c96b4f 100644 --- a/deploy/charts/airlock-microgateway/dashboards/blockLogs.json +++ b/deploy/charts/airlock-microgateway/dashboards/blockLogs.json @@ -60,7 +60,7 @@ } ] }, - "description": "Blocked requests by Airlock Microgateway retrieved from corresponding access logs.\n\nThe dashboard can be filtered by namespace and block type. Column filters on the table allow for even a more granular filtering of the logs.", + "description": "Log entries of threats blocked by Airlock Microgateway.\n\nThe dashboard can be filtered by namespace and block type. Column filters on the table allow for an even more granular filtering of the logs.", "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, @@ -140,7 +140,7 @@ }, { "id": "unit", - "value": "dateTimeAsIso" + "value": "time: YYYY-MM-DD HH:mm:ss.SSS" }, { "id": "custom.filterable" @@ -150,12 +150,12 @@ { "matcher": { "id": "byName", - "options": "Method" + "options": "HTTP Method" }, "properties": [ { "id": "custom.width", - "value": 89 + "value": 140 } ] }, @@ -222,7 +222,7 @@ { "matcher": { "id": "byName", - "options": "Attack Type" + "options": "Block Subtype" }, "properties": [ { @@ -230,18 +230,6 @@ "value": 217 } ] - }, - { - "matcher": { - "id": "byName", - "options": "Application" - }, - "properties": [ - { - "id": "custom.width", - "value": 207 - } - ] } ] }, @@ -266,7 +254,7 @@ "showHeader": true, "sortBy": [] }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -274,62 +262,14 @@ "uid": "${DS_LOKI}" }, "editorMode": "code", - "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_deny_rule\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", details=\"airlock.deny_rules.matches\"\n| label_format block_type=\"deny_rules\", attack_type=`{{ range $q := fromJson .details }} {{ if eq $q.threat_handling_mode \"block\" }} {{ $q.rule_key }} {{ end }} {{ end }}` | block_type=~\"${blockType:regex}\"", - "hide": false, - "queryType": "range", - "refId": "Deny Rule Blocks" - }, - { - "datasource": { - "type": "loki", - "uid": "${DS_LOKI}" - }, - "editorMode": "code", - "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_limit\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", details=\"airlock.limits.matches\"\n| label_format block_type=\"limits\", attack_type=`{{ range $q := fromJson .details }} {{ if eq $q.threat_handling_mode \"block\" }} {{ $q.rule }} {{ end }} {{ end }}` | block_type=~\"${blockType:regex}\"", - "hide": false, - "queryType": "range", - "refId": "Limit Blocks" - }, - { - "datasource": { - "type": "loki", - "uid": "${DS_LOKI}" - }, - "editorMode": "code", - "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_openapi\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", reference=\"airlock.openapi.reference\", constraint=\"airlock.openapi.request.failed_validation.constraint\", position=\"airlock.openapi.request.failed_validation.position\", message=\"airlock.openapi.request.failed_validation.message\"\n| label_format block_type=\"openapi\", attack_type=\"openapi\", details=`{{.reference }}: {{.constraint }} at {{ .position }} ({{ .message }})` | block_type=~\"${blockType:regex}\"", - "hide": false, - "queryType": "range", - "refId": "OpenAPI Blocks" - }, - { - "datasource": { - "type": "loki", - "uid": "${DS_LOKI}" - }, - "editorMode": "code", - "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_parser\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", attack_type=\"airlock.parser\", failed_check=\"airlock.parser.matches[0].failed_check\", message=\"airlock.parser.matches[0].message\"\n| label_format block_type=\"parsing\", attack_type=\"parsing\", details=`{{.failed_check}}: {{.message}}` | block_type=~\"${blockType:regex}\"", - "hide": false, - "queryType": "range", - "refId": "Parser Blocks" - }, - { - "datasource": { - "type": "loki", - "uid": "${DS_LOKI}" - }, - "editorMode": "code", - "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_graphql\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", reference=\"airlock.graphql.reference\", message=\"airlock.graphql.request.failed_validation.message\"\n| label_format block_type=\"graphql\", attack_type=\"graphql\", details=`{{ .reference }}: {{ .message }}` | block_type=~\"${blockType:regex}\"", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", domain=\"url.domain\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", details=\"airlock.actions.block.details\", block_type=\"airlock.actions.block.block_type\", block_subtype=\"airlock.actions.block.block_subtype\"\n| block_type=~\"${blockType:regex}\"", "hide": false, "queryType": "range", - "refId": "GraphQL Blocks" + "refId": "Blocks" } ], "title": "Blocked Request logs", "transformations": [ - { - "id": "merge", - "options": {} - }, { "id": "extractFields", "options": { @@ -344,16 +284,16 @@ "include": { "names": [ "Time", - "attack_type", + "block_subtype", "block_type", "client_ip", "details", + "domain", "http_method", "namespace", "request_id", "request_size", - "url", - "pod" + "url" ] } } @@ -371,30 +311,29 @@ "includeByName": {}, "indexByName": { "Time": 0, - "attack_type": 7, + "block_subtype": 7, "block_type": 6, "client_ip": 9, "details": 8, + "domain": 2, "http_method": 3, "namespace": 1, - "pod": 2, "request_id": 10, "request_size": 5, "url": 4 }, "renameByName": { "Time": "Timestamp", - "attack_type": "Attack Type", + "block_subtype": "Block Subtype", "block_type": "Block Type", "client_ip": "Client IP", "details": "Details", - "http_method": "Method", + "domain": "URL Domain", + "http_method": "HTTP Method", "namespace": "Namespace", - "pod": "Pod", "request_id": "Request ID", "request_size": "Request Size", - "tsNs": "", - "url": "Path" + "url": "URL Path" } } } @@ -409,11 +348,7 @@ "templating": { "list": [ { - "current": { - "selected": false, - "text": "Loki", - "value": "P8E80F9AEF21F6940" - }, + "current": {}, "hide": 2, "includeAll": false, "label": "DS_LOKI", @@ -477,11 +412,7 @@ "type": "query" }, { - "current": { - "selected": false, - "text": "Prometheus", - "value": "PBFA97CFB590B2093" - }, + "current": {}, "hide": 2, "includeAll": false, "label": "DS_PROMETHEUS", @@ -503,7 +434,7 @@ "timeRangeUpdatedDuringEditOrView": false, "timepicker": {}, "timezone": "browser", - "title": "Airlock Microgateway Blocked Request Logs", + "title": "Airlock Microgateway Threats Block - Logs", "uid": "adnyzcvwnyadcc", "version": 3, "weekStart": "" diff --git a/deploy/charts/airlock-microgateway/dashboards/blockMetrics.json b/deploy/charts/airlock-microgateway/dashboards/blockMetrics.json index ba383d2..0b98122 100644 --- a/deploy/charts/airlock-microgateway/dashboards/blockMetrics.json +++ b/deploy/charts/airlock-microgateway/dashboards/blockMetrics.json @@ -58,7 +58,7 @@ } ] }, - "description": "Metrics on requests blocked by Airlock Microgateway.\n\nDashboard can be filtered by namespaces as well as block types.", + "description": "Metrics on threats blocked by Airlock Microgateway.\n\nDashboard can be filtered by namespaces as well as block types.", "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, @@ -88,7 +88,7 @@ "y": 0 }, "id": 6, - "title": "Airlock Microgateway Block Metrics", + "title": "Airlock Microgateway Threats Block - Metrics", "type": "row" }, { @@ -140,7 +140,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -225,7 +225,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -408,7 +408,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "Blocked requests by block type.", + "description": "Blocked threats by block type.", "fieldConfig": { "defaults": { "color": { @@ -448,7 +448,7 @@ } ] }, - "unit": "none" + "unit": "short" }, "overrides": [] }, @@ -482,7 +482,7 @@ "xTickLabelRotation": 0, "xTickLabelSpacing": 0 }, - "pluginVersion": "10.4.3", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -520,7 +520,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "Blocked requests by attack type, which are subsets of the various block types.", + "description": "Blocked threats by block subtype, which are subsets of the various block types.", "fieldConfig": { "defaults": { "color": { @@ -557,7 +557,8 @@ "value": null } ] - } + }, + "unit": "short" }, "overrides": [] }, @@ -587,11 +588,11 @@ "mode": "single", "sort": "none" }, - "xField": "attack_type", + "xField": "block_subtype", "xTickLabelRotation": 0, "xTickLabelSpacing": 0 }, - "pluginVersion": "10.4.3", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -600,14 +601,14 @@ }, "editorMode": "code", "exemplar": false, - "expr": "round(sum by (attack_type) (increase(microgateway_http_downstream_rq_threats_blocked_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "expr": "round(sum by (block_subtype) (increase(microgateway_http_downstream_rq_threats_blocked_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", "instant": true, "legendFormat": "__auto", "range": false, "refId": "A" } ], - "title": "Attack Type", + "title": "Block Subtype", "transformations": [ { "id": "reduce", @@ -630,11 +631,7 @@ "templating": { "list": [ { - "current": { - "selected": false, - "text": "Prometheus", - "value": "PBFA97CFB590B2093" - }, + "current": {}, "hide": 2, "includeAll": false, "label": "Datasource Prometheus", @@ -648,11 +645,7 @@ "type": "datasource" }, { - "current": { - "selected": false, - "text": "Loki", - "value": "P8E80F9AEF21F6940" - }, + "current": {}, "hide": 2, "includeAll": false, "label": "DS_LOKI", @@ -751,7 +744,7 @@ "hidden": false }, "timezone": "browser", - "title": "Airlock Microgateway Block Metrics", + "title": "Airlock Microgateway Threats Block - Metrics", "uid": "ddnqoczu7qvb4cdd3dd", "version": 3, "weekStart": "" diff --git a/deploy/charts/airlock-microgateway/dashboards/headerLogs.json b/deploy/charts/airlock-microgateway/dashboards/headerLogs.json new file mode 100644 index 0000000..a6c4500 --- /dev/null +++ b/deploy/charts/airlock-microgateway/dashboards/headerLogs.json @@ -0,0 +1,378 @@ +{ + "__inputs": [ + { + "name": "DS_LOKI", + "label": "Loki", + "description": "", + "type": "datasource", + "pluginId": "loki", + "pluginName": "Loki" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.2.0" + }, + { + "type": "datasource", + "id": "loki", + "name": "Loki", + "version": "1.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Logs for header rewrites by Airlock Microgateway, retrieved from corresponding access logs.\n\nThe dashboard can be filtered by namespace. Column filters on the table allow for an even more granular filtering of the logs.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "airlock-microgateway" + ], + "targetBlank": true, + "title": "Airlock Microgateway", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "panels": [ + { + "datasource": { + "default": false, + "type": "loki", + "uid": "${DS_LOKI}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": true, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "custom.width", + "value": 221 + }, + { + "id": "custom.filterable" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Timestamp" + }, + "properties": [ + { + "id": "custom.width", + "value": 214 + }, + { + "id": "unit", + "value": "time: YYYY-MM-DD HH:mm:ss.SSS" + }, + { + "id": "custom.filterable" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "HTTP Method" + }, + "properties": [ + { + "id": "custom.width", + "value": 140 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Client IP" + }, + "properties": [ + { + "id": "custom.width", + "value": 138 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Request ID" + }, + "properties": [ + { + "id": "custom.width", + "value": 328 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Request Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 126 + }, + { + "id": "unit", + "value": "bytes" + }, + { + "id": "custom.align", + "value": "right" + } + ] + } + ] + }, + "gridPos": { + "h": 27, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "editorMode": "code", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"header_rewrites\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", domain=\"url.domain\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", header_request_details=\"airlock.actions.header_rewrites.request\", header_response_details=\"airlock.actions.header_rewrites.response\", log_type=\"event.dataset\" | log_type = `envoy.access`", + "hide": false, + "queryType": "range", + "refId": "Header Rewrites" + } + ], + "title": "Header Rewrite Logs", + "transformations": [ + { + "id": "extractFields", + "options": { + "format": "json", + "source": "labels" + } + }, + { + "id": "filterFieldsByName", + "options": { + "byVariable": false, + "include": { + "names": [ + "Time", + "client_ip", + "domain", + "header_request_details", + "header_response_details", + "http_method", + "namespace", + "request_id", + "request_size", + "url" + ] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Line": true, + "id": true, + "labelTypes": true, + "labels": true, + "tsNs": false + }, + "includeByName": {}, + "indexByName": { + "Time": 0, + "client_ip": 8, + "domain": 2, + "header_request_details": 6, + "header_response_details": 7, + "http_method": 3, + "namespace": 1, + "request_id": 9, + "request_size": 5, + "url": 4 + }, + "renameByName": { + "Time": "Timestamp", + "client_ip": "Client IP", + "details": "Details", + "domain": "URL Domain", + "header_request_details": "Request Header Actions", + "header_response_details": "Response Header Actions", + "http_method": "HTTP Method", + "namespace": "Namespace", + "request_id": "Request ID", + "request_size": "Request Size", + "url": "URL Path" + } + } + } + ], + "type": "table" + } + ], + "schemaVersion": 39, + "tags": [ + "airlock-microgateway" + ], + "templating": { + "list": [ + { + "current": {}, + "hide": 2, + "includeAll": false, + "label": "DS_LOKI", + "multi": false, + "name": "DS_LOKI", + "options": [], + "query": "loki", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_http_rq_total,namespace)", + "hide": 0, + "includeAll": true, + "label": "Application Namespace", + "multi": true, + "name": "namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_http_rq_total,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + }, + { + "current": {}, + "hide": 2, + "includeAll": false, + "label": "DS_PROMETHEUS", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Airlock Microgateway Header Rewrites - Logs", + "uid": "adnydadenyadcc", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/deploy/charts/airlock-microgateway/dashboards/license.json b/deploy/charts/airlock-microgateway/dashboards/license.json index b9d5777..1488632 100644 --- a/deploy/charts/airlock-microgateway/dashboards/license.json +++ b/deploy/charts/airlock-microgateway/dashboards/license.json @@ -29,6 +29,12 @@ "name": "Stat", "version": "" }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + }, { "type": "panel", "id": "timeseries", @@ -52,6 +58,7 @@ } ] }, + "description": "Overview on Airlock Microgateway License attributes and usage.", "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, @@ -78,7 +85,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "License status of Airlock Microgateway.", + "description": "Aggregated status of the Airlock Microgateway licenses selected in the dashboard filter.", "fieldConfig": { "defaults": { "color": { @@ -125,6 +132,7 @@ "graphMode": "area", "justifyMode": "auto", "orientation": "auto", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -136,7 +144,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -145,7 +153,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "min(microgateway_license_valid{namespace=~\"${operator_namespace.regex}\"})", + "expr": "min(microgateway_license_valid * on (service,instance) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"})", "instant": true, "legendFormat": "License Status", "range": false, @@ -160,7 +168,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "Expiry date of the Airlock Microgateway license associated with the selected operator.", + "description": "Next upcoming expiry date over all Airlock Microgateway licenses selected in the dashboard filter.", "fieldConfig": { "defaults": { "color": { @@ -193,6 +201,7 @@ "graphMode": "none", "justifyMode": "auto", "orientation": "auto", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -204,7 +213,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -213,7 +222,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "min(microgateway_license_expiry_timestamp_seconds{namespace=~\"${operator_namespace.regex}\"})*1000", + "expr": "min(microgateway_license_expiry_timestamp_seconds * on (service, namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"})*1000", "instant": true, "legendFormat": "Expiry Date (MM/DD/YYYY)", "range": false, @@ -228,7 +237,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "Number of licensed requests for applications protected by Airlock Microgateway.", + "description": "Sum of the number licensed requests over all Airlock Microgateway license selected in the dashboard filter.", "fieldConfig": { "defaults": { "color": { @@ -261,6 +270,7 @@ "graphMode": "none", "justifyMode": "auto", "orientation": "auto", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -272,7 +282,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -281,7 +291,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sum(microgateway_license_max_rq_count_per_month{namespace=~\"${operator_namespace.regex}\"})", + "expr": "sum(topk(1, (microgateway_license_max_rq_count_per_month > 0) * on (service, namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"}) by (id))", "instant": true, "legendFormat": "Licensed Requests", "range": false, @@ -296,7 +306,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "Estimated number of requests protected by Airlock Microgateway over 30 days based on the last 7 days.", + "description": "Sum of the estimated number of requests over 30 days based on the last 7 days over all Airlock Microgateway licenses selected in the dashboard filter.", "fieldConfig": { "defaults": { "color": { @@ -329,6 +339,7 @@ "graphMode": "none", "justifyMode": "auto", "orientation": "auto", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -340,7 +351,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -349,7 +360,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sum(increase(microgateway_license_http_rq_total{job=~\"${operator_namespace.regex}/.*-engine\"}[7d]))/7*30", + "expr": "(sum((label_replace(increase(microgateway_license_http_rq_total[7d]), \"namespace\", \"$1\", \"job\", \"(.+)/.*\")) * on(namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"}))/7*30", "instant": true, "legendFormat": "Estimated Requests", "range": false, @@ -378,6 +389,7 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -418,8 +430,8 @@ "overrides": [] }, "gridPos": { - "h": 12, - "w": 16, + "h": 13, + "w": 24, "x": 0, "y": 4 }, @@ -444,17 +456,551 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "sum(avg_over_time(increase(microgateway_license_http_rq_total{job=~\"${operator_namespace.regex}/.*-engine\"}[7d])[2m:30s]))", + "expr": " sum((label_replace(avg_over_time(increase(microgateway_license_http_rq_total[7d])[2m:30s]), \"namespace\", \"$1\", \"job\", \"(.+)/.*\")) * on(namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"})", + "hide": false, "instant": false, "legendFormat": "# Requests per week", "range": true, - "refId": "A" + "refId": "C" } ], "title": "Processed Requests per week", "type": "timeseries" + }, + { + "datasource": { + "default": false, + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Estimated number of requests over 30 days based on the last 7 days per operator namespace for the Airlock Microgateway licenses selected in the dashboard filter.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "License ID" + }, + "properties": [ + { + "id": "custom.width", + "value": 330 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Requests over 30 days (estimated)" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "mappings", + "value": [ + { + "options": { + "match": "null+nan", + "result": { + "index": 0, + "text": "0" + } + }, + "type": "special" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Operator Namespace" + }, + "properties": [ + { + "id": "custom.width", + "value": 307 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 11, + "x": 0, + "y": 17 + }, + "id": 7, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "frameIndex": 1, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "(sum by (namespace, id) ((label_replace(increase(microgateway_license_http_rq_total[7d]), \"namespace\", \"$1\", \"job\", \"(.+)/.*\")) * on(namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"}))/7*30", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "Est. Usage over 30 days" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "(min by(namespace) (microgateway_build_info{container=\"manager\"})) * on (namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"}", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "Engine License" + } + ], + "title": "Usage by Operator Namespace", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Value #Engine License": true, + "Value #Licensed Req": false, + "container": true, + "endpoint": true, + "instance": true, + "job": true, + "namespace": false, + "pod": true, + "service": true, + "version": true + }, + "includeByName": {}, + "indexByName": { + "Time": 0, + "Value": 3, + "id": 2, + "namespace": 1 + }, + "renameByName": { + "Value #Est. Usage over 30 days": "Requests over 30 days (estimated)", + "Value #License Expiry Date": "Expiry Date", + "Value #License Type": "License Type", + "Value #Licensed Req": "Licensed Requests", + "Value #Validity": "Valid", + "id": "License ID", + "namespace": "Operator Namespace" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Metadata for the Airlock Microgateway licenses selected in the dashboard filter.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "License ID" + }, + "properties": [ + { + "id": "custom.width", + "value": 321 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Valid" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "0": { + "color": "red", + "index": 1, + "text": "Invalid" + }, + "1": { + "color": "green", + "index": 0, + "text": "Valid" + } + }, + "type": "value" + }, + { + "options": { + "match": "null+nan", + "result": { + "color": "red", + "index": 2, + "text": "Invalid" + } + }, + "type": "special" + } + ] + }, + { + "id": "custom.width", + "value": 65 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "License Type" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "0": { + "index": 1, + "text": "Community" + }, + "1": { + "index": 0, + "text": "Premium" + } + }, + "type": "value" + }, + { + "options": { + "match": "null+nan", + "result": { + "index": 2, + "text": "n/a" + } + }, + "type": "special" + } + ] + }, + { + "id": "custom.width", + "value": 109 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Expiry Date" + }, + "properties": [ + { + "id": "unit", + "value": "time:L" + }, + { + "id": "custom.width", + "value": 130 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Requests over 30 days (estimated)" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "mappings", + "value": [ + { + "options": { + "match": "null+nan", + "result": { + "index": 0, + "text": "0" + } + }, + "type": "special" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Licensed Requests" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "custom.width", + "value": 160 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 13, + "x": 11, + "y": 17 + }, + "id": 8, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "frameIndex": 1, + "showHeader": true, + "sortBy": [ + { + "desc": false, + "displayName": "Expiry Date" + } + ] + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "min by (id) (microgateway_license_valid * on (service, namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"})", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "Validity" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "topk(1,microgateway_license_max_rq_count_per_month * on (service, namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"})by (id)", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "Licensed Req" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "min by (id) (microgateway_license_is_premium * on (service, namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"})", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "License Type" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "min by (id) (microgateway_license_expiry_timestamp_seconds * on (service, namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"})*1000", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "License Expiry Date" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "(sum by (id) ((label_replace(increase(microgateway_license_http_rq_total[7d]), \"namespace\", \"$1\", \"job\", \"(.+)/.*\")) * on(namespace) group_left(id) microgateway_license_info{id=~\"${license_id.regex}\"}))/7*30", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "Est. Usage over 30 days" + } + ], + "title": "License Overview", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Value #Licensed Req": false, + "container": true, + "endpoint": true, + "instance": true, + "job": true, + "namespace": true, + "pod": true, + "service": true + }, + "includeByName": {}, + "indexByName": {}, + "renameByName": { + "Value #Est. Usage over 30 days": "Requests over 30 days (estimated)", + "Value #License Expiry Date": "Expiry Date", + "Value #License Type": "License Type", + "Value #Licensed Req": "Licensed Requests", + "Value #Validity": "Valid", + "id": "License ID", + "namespace": "Operator Namespace" + } + } + }, + { + "id": "filterByValue", + "options": { + "filters": [ + { + "config": { + "id": "equal", + "options": { + "value": "" + } + }, + "fieldName": "License ID" + } + ], + "match": "any", + "type": "exclude" + } + } + ], + "type": "table" } ], + "refresh": "", "schemaVersion": 39, "tags": [ "airlock-microgateway" @@ -462,11 +1008,7 @@ "templating": { "list": [ { - "current": { - "selected": false, - "text": "Prometheus", - "value": "PBFA97CFB590B2093" - }, + "current": {}, "hide": 2, "includeAll": false, "label": "DS_PROMETHEUS", @@ -486,17 +1028,17 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "definition": "label_values(microgateway_license_valid,namespace)", + "definition": "label_values(microgateway_license_info,id)", "description": "", "hide": 0, - "includeAll": false, - "label": "Operator Namespace", - "multi": false, - "name": "operator_namespace", + "includeAll": true, + "label": "License ID", + "multi": true, + "name": "license_id", "options": [], "query": { "qryType": 1, - "query": "label_values(microgateway_license_valid,namespace)", + "query": "label_values(microgateway_license_info,id)", "refId": "PrometheusVariableQueryEditor-VariableQuery" }, "refresh": 2, diff --git a/deploy/charts/airlock-microgateway/dashboards/logOnlyLogs.json b/deploy/charts/airlock-microgateway/dashboards/logOnlyLogs.json new file mode 100644 index 0000000..6d7ae7f --- /dev/null +++ b/deploy/charts/airlock-microgateway/dashboards/logOnlyLogs.json @@ -0,0 +1,382 @@ +{ + "__inputs": [ + { + "name": "DS_LOKI", + "label": "Loki", + "description": "", + "type": "datasource", + "pluginId": "loki", + "pluginName": "Loki" + }, + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.2.0" + }, + { + "type": "datasource", + "id": "loki", + "name": "Loki", + "version": "1.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Log entries of threats logged in log-only mode by Airlock Microgateway.\n\nThe dashboard can be filtered by namespace. Column filters on the table allow for an even more granular filtering of the logs.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "airlock-microgateway" + ], + "targetBlank": true, + "title": "Airlock Microgateway", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "panels": [ + { + "datasource": { + "default": false, + "type": "loki", + "uid": "${DS_LOKI}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": true, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "custom.width", + "value": 328 + }, + { + "id": "custom.filterable" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Timestamp" + }, + "properties": [ + { + "id": "custom.width", + "value": 176 + }, + { + "id": "unit", + "value": "time: YYYY-MM-DD HH:mm:ss.SSS" + }, + { + "id": "custom.filterable" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "HTTP Method" + }, + "properties": [ + { + "id": "custom.width", + "value": 132 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Client IP" + }, + "properties": [ + { + "id": "custom.width", + "value": 137 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Request ID" + }, + "properties": [ + { + "id": "custom.width", + "value": 328 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Request Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 126 + }, + { + "id": "unit", + "value": "bytes" + }, + { + "id": "custom.align", + "value": "right" + } + ] + } + ] + }, + "gridPos": { + "h": 27, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "editorMode": "code", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= `log_only` |= `envoy.access` | json http_method=\"http.request.method\", url=\"url.path\", domain=\"url.domain\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", details=\"airlock.actions.log_only\", log_type=\"event.dataset\" | label_format log_count=`{{ len (fromJson .details) }}` | log_type = `envoy.access` | log_count > 0", + "hide": false, + "queryType": "range", + "refId": "Log Only Logs" + } + ], + "title": "Threats Logs Log-Only", + "transformations": [ + { + "id": "extractFields", + "options": { + "format": "json", + "source": "labels" + } + }, + { + "id": "filterFieldsByName", + "options": { + "byVariable": false, + "include": { + "names": [ + "Time", + "client_ip", + "details", + "domain", + "http_method", + "namespace", + "request_id", + "request_size", + "url" + ] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Line": true, + "id": true, + "labelTypes": true, + "labels": true, + "tsNs": false + }, + "includeByName": {}, + "indexByName": { + "Time": 0, + "client_ip": 8, + "details": 7, + "domain": 2, + "http_method": 4, + "namespace": 1, + "request_id": 9, + "request_size": 6, + "url": 5 + }, + "renameByName": { + "Time": "Timestamp", + "client_ip": "Client IP", + "details": "Details", + "domain": "URL Domain", + "http_method": "HTTP Method", + "namespace": "Namespace", + "request_id": "Request ID", + "request_size": "Request Size", + "url": "URL Path" + } + } + } + ], + "type": "table" + } + ], + "schemaVersion": 39, + "tags": [ + "airlock-microgateway" + ], + "templating": { + "list": [ + { + "current": {}, + "hide": 2, + "includeAll": false, + "label": "DS_LOKI", + "multi": false, + "name": "DS_LOKI", + "options": [], + "query": "loki", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_http_rq_total,namespace)", + "hide": 0, + "includeAll": true, + "label": "Application Namespace", + "multi": true, + "name": "namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_http_rq_total,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + }, + { + "current": {}, + "hide": 2, + "includeAll": false, + "label": "DS_PROMETHEUS", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Airlock Microgateway Threats LogOnly - Logs", + "uid": "adnasdfdwnyadcc", + "version": 7, + "weekStart": "" +} \ No newline at end of file diff --git a/deploy/charts/airlock-microgateway/dashboards/logOnlyMetrics.json b/deploy/charts/airlock-microgateway/dashboards/logOnlyMetrics.json new file mode 100644 index 0000000..137e28e --- /dev/null +++ b/deploy/charts/airlock-microgateway/dashboards/logOnlyMetrics.json @@ -0,0 +1,621 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "barchart", + "name": "Bar chart", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.2.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Metrics on threats logged by Airlock Microgateway in threat handling mode LogOnly.\n\nDashboard can be filtered by namespaces as well as block types.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "airlock-microgateway" + ], + "targetBlank": true, + "title": "Airlock Microgateway", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 6, + "title": "Airlock Microgateway Threats LogOnly - Metrics", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Number of threats logged by Airlock Microgateway in threat handling mode LogOnly.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [ + { + "options": { + "match": "nan", + "result": { + "index": 0, + "text": "n/a" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "round(sum(increase(microgateway_http_downstream_rq_threats_logged_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "Logged threats in LogOnly mode", + "range": false, + "refId": "A", + "useBackend": false + } + ], + "title": "Threats - LogOnly", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Number of threats per second handled in LogOnly mode.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "orange", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "left", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 25, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 20, + "x": 0, + "y": 5 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timezone": [ + "" + ], + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(rate(microgateway_http_downstream_rq_threats_logged_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m]))", + "instant": false, + "legendFormat": "Number of threats per second", + "range": true, + "refId": "LogOnly Events" + } + ], + "title": "Threats - LogOnly", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Number of threats in LogOnly mode by block type.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "super-light-orange", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 0, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "fieldMinMax": false, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 10, + "x": 0, + "y": 15 + }, + "id": 4, + "options": { + "barRadius": 0, + "barWidth": 0.8, + "fullHighlight": false, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "orientation": "horizontal", + "showValue": "never", + "stacking": "none", + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "asc" + }, + "xField": "block_type", + "xTickLabelRotation": 0, + "xTickLabelSpacing": 0 + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "round(sum by (block_type) (increase(microgateway_http_downstream_rq_threats_logged_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "format": "time_series", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Block Type", + "transformations": [ + { + "id": "reduce", + "options": { + "includeTimeField": false, + "labelsToFields": true, + "mode": "seriesToRows", + "reducers": [ + "sum" + ] + } + } + ], + "type": "barchart" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Number of threats in LogOnly mode by block subtype, which are subsets of the various block types.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "light-orange", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 10, + "x": 10, + "y": 15 + }, + "id": 5, + "options": { + "barRadius": 0, + "barWidth": 0.8, + "fullHighlight": false, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "orientation": "horizontal", + "showValue": "never", + "stacking": "none", + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + }, + "xField": "block_subtype", + "xTickLabelRotation": 0, + "xTickLabelSpacing": 0 + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "round(sum by (block_subtype) (increase(microgateway_http_downstream_rq_threats_logged_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Block Subtype", + "transformations": [ + { + "id": "reduce", + "options": { + "labelsToFields": true, + "reducers": [ + "sum" + ] + } + } + ], + "type": "barchart" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [ + "airlock-microgateway" + ], + "templating": { + "list": [ + { + "current": {}, + "hide": 2, + "includeAll": false, + "label": "Datasource Prometheus", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": {}, + "hide": 2, + "includeAll": false, + "label": "DS_LOKI", + "multi": false, + "name": "DS_LOKI", + "options": [], + "query": "loki", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_valid,namespace)", + "hide": 0, + "includeAll": true, + "label": "Operator Namespace", + "multi": true, + "name": "operator_namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_valid,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": ".*", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_http_rq_total,namespace)", + "hide": 0, + "includeAll": true, + "label": "Application Namespace", + "multi": true, + "name": "namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_http_rq_total,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_http_downstream_rq_threats_logged_total,block_type)", + "hide": 0, + "includeAll": true, + "label": "Block Type", + "multi": true, + "name": "blockType", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_http_downstream_rq_threats_logged_total,block_type)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": { + "hidden": false + }, + "timezone": "browser", + "title": "Airlock Microgateway Threats LogOnly - Metrics", + "uid": "ddnqoczu7qv2mfmsd3dd", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/deploy/charts/airlock-microgateway/dashboards/overview.json b/deploy/charts/airlock-microgateway/dashboards/overview.json index 0942766..8a9c913 100644 --- a/deploy/charts/airlock-microgateway/dashboards/overview.json +++ b/deploy/charts/airlock-microgateway/dashboards/overview.json @@ -137,7 +137,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -205,7 +205,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -290,7 +290,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -376,7 +376,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -566,7 +566,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "Requests blocked by Airlock Microgateway categorized by their corresponding type.", + "description": "Threats blocked by Airlock Microgateway categorized by their corresponding block type.", "fieldConfig": { "defaults": { "color": { @@ -670,7 +670,7 @@ } ] }, - "pluginVersion": "11.0.0", + "pluginVersion": "10.2.0", "targets": [ { "datasource": { @@ -686,7 +686,7 @@ "refId": "Block Types" } ], - "title": "Blocked Requests by Type", + "title": "Blocked Threats by Block Type", "transformations": [ { "id": "timeSeriesTable", @@ -1055,11 +1055,7 @@ "templating": { "list": [ { - "current": { - "selected": false, - "text": "Prometheus", - "value": "PBFA97CFB590B2093" - }, + "current": {}, "hide": 2, "includeAll": false, "label": "DS_PROMETHEUS", diff --git a/deploy/charts/airlock-microgateway/templates/NOTES.txt b/deploy/charts/airlock-microgateway/templates/NOTES.txt index 6e5ce21..a607483 100644 --- a/deploy/charts/airlock-microgateway/templates/NOTES.txt +++ b/deploy/charts/airlock-microgateway/templates/NOTES.txt @@ -1,13 +1,27 @@ Thank you for installing Airlock Microgateway. +{{- if .Values.operator.gatewayAPI.enabled }} + +K8s Gateway API support enabled. +Note that the K8s Gateway API support is an incubating Airlock Microgateway feature. We encourage you to try the installation and configuration for testing and evaluation. Your feedback is welcome. + + {{- if or .Values.operator.watchNamespaces .Values.operator.watchNamespaceSelector -}} + {{- fail ` + +K8s Gateway API is only supported using the 'AllNamespaces' installation mode type, ensure that 'operator.watchNamespaces' and 'operator.watchNamespaceSelector' are not configured. +` + -}} + {{- end -}} +{{- end }} Please ensure the following prerequisites are fulfilled: -* Cert-Manager is installed. +* cert-manager is installed. https://cert-manager.io/docs/installation/helm/ -* Airlock Microgateway CNI is also installed on the cluster. - https://artifacthub.io/packages/helm/airlock-microgateway-cni/microgateway-cni -* A valid Airlock Microgateway license is deployed in the Kubernetes secret 'airlock-microgateway-license'. +* A valid Airlock Microgateway license is deployed in the Kubernetes secret '{{ .Release.Namespace }}/{{ .Values.license.secretName }}' * Get a free Community license: https://airlock.com/en/microgateway-community * Order a Premium license: https://airlock.com/en/microgateway-premium +* Airlock Microgateway CNI is installed on the cluster, when running data plane mode sidecar + https://artifacthub.io/packages/helm/airlock-microgateway-cni/microgateway-cni. + For more information about data plane modes, see https://docs.airlock.com/microgateway/{{ include "airlock-microgateway.docsVersion" . }}/#data/1660804709650.html Further information: * Documentation: https://docs.airlock.com/microgateway/{{ include "airlock-microgateway.docsVersion" . }} diff --git a/deploy/charts/airlock-microgateway/templates/operator/_rbac.gen.tpl b/deploy/charts/airlock-microgateway/templates/operator/_rbac.gen.tpl index 83b314c..faa078b 100644 --- a/deploy/charts/airlock-microgateway/templates/operator/_rbac.gen.tpl +++ b/deploy/charts/airlock-microgateway/templates/operator/_rbac.gen.tpl @@ -8,6 +8,8 @@ Operator rbac permission rules - "" resources: - configmaps + - namespaces + - replicasets verbs: - get - list @@ -19,14 +21,6 @@ Operator rbac permission rules verbs: - create - patch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - - list - - watch - apiGroups: - "" resources: @@ -60,80 +54,82 @@ Operator rbac permission rules - delete - get - list + - patch - update - watch - apiGroups: - - microgateway.airlock.com - resources: - - accesscontrols - verbs: - - get - - list - - watch -- apiGroups: - - microgateway.airlock.com + - "" resources: - - contentsecurities + - services verbs: + - create - get - list + - patch + - update - watch - apiGroups: - - microgateway.airlock.com + - apiextensions.k8s.io resources: - - denyrules + - customresourcedefinitions verbs: - get - list - watch - apiGroups: - - microgateway.airlock.com + - apps resources: - - envoyclusters + - deployments verbs: + - create - get - list + - patch + - update - watch - apiGroups: - - microgateway.airlock.com + - apps resources: - - envoyconfigurations + - replicasets verbs: - - create - - delete - get - list - patch - update - watch - apiGroups: - - microgateway.airlock.com + - apps resources: - - envoyconfigurations/status + - replicasets/finalizers verbs: - - get - patch - update - apiGroups: - - microgateway.airlock.com + - gateway.networking.k8s.io resources: - - envoyhttpfilters + - gatewayclasses verbs: - get - list + - patch - watch - apiGroups: - - microgateway.airlock.com + - gateway.networking.k8s.io resources: - - graphqls + - gatewayclasses/finalizers + - gatewayclasses/status + - gateways/finalizers + - gateways/status + - httproutes/status verbs: - - get - - list - - watch + - patch + - update - apiGroups: - - microgateway.airlock.com + - gateway.networking.k8s.io resources: - - headerrewrites + - gateways + - httproutes + - referencegrants verbs: - get - list @@ -141,39 +137,24 @@ Operator rbac permission rules - apiGroups: - microgateway.airlock.com resources: + - accesscontrols + - contentsecurities + - contentsecuritypolicies + - denyrules + - envoyclusters + - envoyhttpfilters + - graphqls + - headerrewrites - identitypropagations - verbs: - - get - - list - - watch -- apiGroups: - - microgateway.airlock.com - resources: + - jwks - limits - verbs: - - get - - list - - watch -- apiGroups: - - microgateway.airlock.com - resources: - oidcproviders - verbs: - - get - - list - - watch -- apiGroups: - - microgateway.airlock.com - resources: - oidcrelyingparties - verbs: - - get - - list - - watch -- apiGroups: - - microgateway.airlock.com - resources: - openapis + - parsers + - redisproviders + - sessionhandlings + - telemetries verbs: - get - list @@ -181,27 +162,31 @@ Operator rbac permission rules - apiGroups: - microgateway.airlock.com resources: - - parsers + - contentsecuritypolicies/status verbs: - - get - - list - - watch + - patch + - update - apiGroups: - microgateway.airlock.com resources: - - redisproviders + - envoyconfigurations verbs: + - create + - delete - get - list + - patch + - update - watch - apiGroups: - microgateway.airlock.com resources: - - sessionhandlings + - envoyconfigurations/status + - sidecargateways/status verbs: - get - - list - - watch + - patch + - update - apiGroups: - microgateway.airlock.com resources: @@ -218,20 +203,4 @@ Operator rbac permission rules - sidecargateways/finalizers verbs: - update -- apiGroups: - - microgateway.airlock.com - resources: - - sidecargateways/status - verbs: - - get - - patch - - update -- apiGroups: - - microgateway.airlock.com - resources: - - telemetries - verbs: - - get - - list - - watch {{- end }} diff --git a/deploy/charts/airlock-microgateway/templates/operator/_webhooks.gen.tpl b/deploy/charts/airlock-microgateway/templates/operator/_webhooks.gen.tpl index 02e3048..97474df 100644 --- a/deploy/charts/airlock-microgateway/templates/operator/_webhooks.gen.tpl +++ b/deploy/charts/airlock-microgateway/templates/operator/_webhooks.gen.tpl @@ -76,6 +76,26 @@ Operator validating webhooks resources: - accesscontrols sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-contentsecuritypolicy + failurePolicy: Fail + name: validate-contentsecuritypolicy.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - contentsecuritypolicies + sideEffects: None - admissionReviewVersions: - v1 clientConfig: @@ -196,6 +216,26 @@ Operator validating webhooks resources: - identitypropagations sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-jwks + failurePolicy: Fail + name: validate-jwks.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - jwks + sideEffects: None - admissionReviewVersions: - v1 clientConfig: @@ -316,6 +356,26 @@ Operator validating webhooks resources: - redisproviders sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-sessionhandling + failurePolicy: Fail + name: validate-sessionhandling.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - sessionhandlings + sideEffects: None - admissionReviewVersions: - v1 clientConfig: diff --git a/deploy/charts/airlock-microgateway/templates/operator/configmap.yaml b/deploy/charts/airlock-microgateway/templates/operator/configmap.yaml index 95e52d7..276a632 100644 --- a/deploy/charts/airlock-microgateway/templates/operator/configmap.yaml +++ b/deploy/charts/airlock-microgateway/templates/operator/configmap.yaml @@ -190,8 +190,8 @@ data: stats_tags: - tag_name: "block_type" regex: "\\.(block_type\\.([^.]+))" - - tag_name: "attack_type" - regex: "\\.(attack_type\\.([^.]+))" + - tag_name: "block_subtype" + regex: "\\.(block_subtype\\.([^.]+))" - tag_name: "envoy_cluster_name" regex: "\\.(cluster\\.([^.]+))" - tag_name: "version" @@ -364,6 +364,10 @@ data: securityContext: {{- include "airlock-microgateway.restrictedSecurityContext" . | nindent 6 }} runAsUser: $(SECURITYCONTEXT_UID) + {{- with .Values.networkValidator.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} operator_config.yaml: | apiVersion: config.airlock.com/v1alpha1 kind: OperatorConfig @@ -392,3 +396,10 @@ data: list: {{- toYaml . | nindent 8 }} {{- end }} + {{- with $.Values.operator.gatewayAPI }} + gatewayAPI: + enabled: {{ .enabled }} + {{- if .controllerName }} + controllerName: {{ .controllerName }} + {{- end }} + {{- end }} \ No newline at end of file diff --git a/deploy/charts/airlock-microgateway/templates/tests/test-install.yaml b/deploy/charts/airlock-microgateway/templates/tests/test-install.yaml index ab82abe..721ae2b 100644 --- a/deploy/charts/airlock-microgateway/templates/tests/test-install.yaml +++ b/deploy/charts/airlock-microgateway/templates/tests/test-install.yaml @@ -138,7 +138,7 @@ spec: echo "### Waiting for Microgateway Operator Deployments to be ready" if ! kubectl rollout status -n {{ .Release.Namespace }} --timeout=90s \ deployments/{{ include "airlock-microgateway.operator.fullname" . }}; then - fail 'Timout occurred' + fail 'Timeout occurred' fi echo "" @@ -189,7 +189,7 @@ spec: echo "### Waiting for '{{ include "airlock-microgateway.fullname" . }}-test-backend' to be ready" if ! kubectl rollout status -n {{ .Release.Namespace }} statefulset/{{ include "airlock-microgateway.fullname" . }}-test-backend --timeout=90s; then - fail 'Timout occurred' + fail 'Timeout occurred' fi echo "" diff --git a/deploy/charts/airlock-microgateway/tests/notes_test.yaml b/deploy/charts/airlock-microgateway/tests/notes_test.yaml index f40eefe..550edc3 100644 --- a/deploy/charts/airlock-microgateway/tests/notes_test.yaml +++ b/deploy/charts/airlock-microgateway/tests/notes_test.yaml @@ -38,5 +38,33 @@ tests: set: tests.enabled: true operator.watchNamespaces: [ "foo", "mytestnamespace", "bar" ] + asserts: + - notFailedTemplate: {} + - it: should fail if Gateway API is enabled and watch namespaces are set + release: + name: myoperator + namespace: mytestnamespace + set: + operator.gatewayAPI.enabled: true + operator.watchNamespaces: [ "foo", "bar" ] + asserts: + - failedTemplate: {} + - it: should fail if Gateway API is enabled and watch namespace selector is set + release: + name: myoperator + namespace: mytestnamespace + set: + operator.gatewayAPI.enabled: true + operator.watchNamespaceSelector: + matchLabels: + foo: bar + asserts: + - failedTemplate: {} + - it: should succeed if Gateway API is enabled and neither a watch namespace nor watch namespace selector is set + release: + name: myoperator + namespace: mytestnamespace + set: + operator.gatewayAPI.enabled: true asserts: - notFailedTemplate: {} \ No newline at end of file diff --git a/deploy/charts/airlock-microgateway/tests/operator/dashboard_test.yaml b/deploy/charts/airlock-microgateway/tests/operator/dashboard_test.yaml index a670e53..0fda371 100644 --- a/deploy/charts/airlock-microgateway/tests/operator/dashboard_test.yaml +++ b/deploy/charts/airlock-microgateway/tests/operator/dashboard_test.yaml @@ -25,7 +25,7 @@ tests: dashboards.create: true asserts: - hasDocuments: - count: 4 + count: 7 - equal: path: metadata.name value: myoperator-microgateway-dashboard-blocklogs @@ -36,12 +36,24 @@ tests: documentIndex: 1 - equal: path: metadata.name - value: myoperator-microgateway-dashboard-license + value: myoperator-microgateway-dashboard-headerlogs documentIndex: 2 - equal: path: metadata.name - value: myoperator-microgateway-dashboard-overview + value: myoperator-microgateway-dashboard-license documentIndex: 3 + - equal: + path: metadata.name + value: myoperator-microgateway-dashboard-logonlylogs + documentIndex: 4 + - equal: + path: metadata.name + value: myoperator-microgateway-dashboard-logonlymetrics + documentIndex: 5 + - equal: + path: metadata.name + value: myoperator-microgateway-dashboard-overview + documentIndex: 6 - it: should be possible to only enable license dashboard release: @@ -56,6 +68,12 @@ tests: create: false blockMetrics: create: false + headerLogs: + create: false + logOnlyMetrics: + create: false + logOnlyLogs: + create: false asserts: - hasDocuments: count: 1 @@ -76,6 +94,12 @@ tests: create: false license: create: false + headerLogs: + create: false + logOnlyMetrics: + create: false + logOnlyLogs: + create: false asserts: - hasDocuments: count: 1 @@ -96,6 +120,12 @@ tests: create: false blockMetrics: create: false + headerLogs: + create: false + logOnlyMetrics: + create: false + logOnlyLogs: + create: false asserts: - hasDocuments: count: 1 @@ -103,6 +133,32 @@ tests: path: metadata.name value: myoperator-microgateway-dashboard-overview + - it: should be possible to only enable headerLogs dashboard + release: + name: myoperator + set: + dashboards: + create: true + instances: + overview: + create: false + license: + create: false + blockLogs: + create: false + blockMetrics: + create: false + logOnlyMetrics: + create: false + logOnlyLogs: + create: false + asserts: + - hasDocuments: + count: 1 + - equal: + path: metadata.name + value: myoperator-microgateway-dashboard-headerlogs + - it: should be possible to only enable blockLogs dashboard release: name: myoperator @@ -116,6 +172,12 @@ tests: create: false blockMetrics: create: false + headerLogs: + create: false + logOnlyMetrics: + create: false + logOnlyLogs: + create: false asserts: - hasDocuments: count: 1 @@ -123,6 +185,58 @@ tests: path: metadata.name value: myoperator-microgateway-dashboard-blocklogs + - it: should be possible to only enable logOnlyMetrics dashboard + release: + name: myoperator + set: + dashboards: + create: true + instances: + license: + create: false + overview: + create: false + blockMetrics: + create: false + headerLogs: + create: false + blockLogs: + create: false + logOnlyLogs: + create: false + asserts: + - hasDocuments: + count: 1 + - equal: + path: metadata.name + value: myoperator-microgateway-dashboard-logonlymetrics + + - it: should be possible to only enable logOnlyLogs dashboard + release: + name: myoperator + set: + dashboards: + create: true + instances: + license: + create: false + overview: + create: false + blockMetrics: + create: false + headerLogs: + create: false + blockLogs: + create: false + logOnlyMetrics: + create: false + asserts: + - hasDocuments: + count: 1 + - equal: + path: metadata.name + value: myoperator-microgateway-dashboard-logonlylogs + - it: should set grafana label correctly set: dashboards.create: true diff --git a/deploy/charts/airlock-microgateway/values.schema.json b/deploy/charts/airlock-microgateway/values.schema.json index 173d6b0..05c7d77 100644 --- a/deploy/charts/airlock-microgateway/values.schema.json +++ b/deploy/charts/airlock-microgateway/values.schema.json @@ -152,6 +152,22 @@ "create" ], "additionalProperties": false + }, + "gatewayAPI": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "controllerName" : { + "type": "string", + "pattern": "^microgateway\\.airlock\\.com\/[A-Za-z0-9\/\\-._~%!$&'()*+,;=:]+$" + } + }, + "required": [ + "enabled" + ], + "additionalProperties": false } }, "oneOf": [ @@ -241,10 +257,14 @@ "properties": { "image": { "$ref": "#/definitions/Image" + }, + "resources": { + "type": "object" } }, "required": [ - "image" + "image", + "resources" ], "additionalProperties": false }, @@ -322,13 +342,25 @@ }, "blockLogs" : { "$ref": "#/definitions/DashboardInstance" + }, + "headerLogs" : { + "$ref": "#/definitions/DashboardInstance" + }, + "logOnlyMetrics" : { + "$ref": "#/definitions/DashboardInstance" + }, + "logOnlyLogs" : { + "$ref": "#/definitions/DashboardInstance" } }, "required": [ "overview", "license", "blockMetrics", - "blockLogs" + "blockLogs", + "headerLogs", + "logOnlyMetrics", + "logOnlyLogs" ], "additionalProperties": false } diff --git a/deploy/charts/airlock-microgateway/values.yaml b/deploy/charts/airlock-microgateway/values.yaml index af720d5..7d35047 100644 --- a/deploy/charts/airlock-microgateway/values.yaml +++ b/deploy/charts/airlock-microgateway/values.yaml @@ -26,10 +26,10 @@ operator: # -- Image repository from which to pull the Airlock Microgateway Operator image. repository: "quay.io/airlock/microgateway-operator" # -- Image tag to pull. - tag: "4.3.4" + tag: "4.4.0" # -- SHA256 image digest to pull (in the format "sha256:c79ee3f85862fb386e9dd62b901b607161d27807f512d7fbdece05e9ee3d7c63"). # Overrides tag when specified. - digest: "sha256:6819c78d5570de66edce6c13964c6e1b4cc4746d0c0bc6f4975cd38e324828c0" + digest: "sha256:80cbae58ad9badd9395fa09a7b0576561821121b8353146bbd6efa2240ab5d97" # -- Pull policy for this image. pullPolicy: IfNotPresent # -- Annotations to add to all Pods. @@ -103,16 +103,23 @@ operator: # -- Labels to add to the ServiceMonitor. labels: {} # release: "" + # Configures the Kubernetes Gateway API integration. + gatewayAPI: + # -- Whether to enable the Kubernetes Gateway API related controllers. + # Requires that the gateway.networking.k8s.io/v1 resources are installed on the cluster. + enabled: false + # -- Controller name referred in the GatewayClasses managed by this operator. The value must be a path prefixed by the domain `microgateway.airlock.com`. + controllerName: microgateway.airlock.com/gatewayclass-controller engine: # Specifies the Airlock Microgateway Engine image. image: # -- Image repository from which to pull the Airlock Microgateway Engine image. repository: "quay.io/airlock/microgateway-engine" # -- Image tag to pull. - tag: "4.3.4" + tag: "4.4.0" # -- SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). # Overrides tag when specified. - digest: "sha256:91e05c509bed3b51ff4888d7475980d56cbc85db121aa766d1bde413204f9070" + digest: "sha256:c29adf07e7536b72447ea694d0e19fe19235306c26d412a9abc43e4dd99b84c8" # -- Pull policy for this image. pullPolicy: IfNotPresent # -- Resource restrictions to apply to the Airlock Microgateway Engine container. @@ -141,21 +148,29 @@ networkValidator: repository: "cgr.dev/chainguard/netcat" # -- Image tag to pull. tag: "" - # -- SHA256 image digest to pull (in the format "sha256:7a73d4b82a2d4165bbc5efa55de4fee9d43f2b1c1edb3505cdc8afd1361bad9b"). + # -- SHA256 image digest to pull (in the format "sha256:05585644690678ae6453ab12e3a5f899e7be5ab70f56c6bf1c4484d3b53587d2"). # Overrides tag when specified. - digest: "sha256:7a73d4b82a2d4165bbc5efa55de4fee9d43f2b1c1edb3505cdc8afd1361bad9b" + digest: "sha256:05585644690678ae6453ab12e3a5f899e7be5ab70f56c6bf1c4484d3b53587d2" # -- Pull policy for this image. pullPolicy: IfNotPresent + # -- Resource restrictions to apply to the Airlock Microgateway Network Validator init-container. + resources: + limits: + cpu: 25m + memory: 12Mi + requests: + cpu: 5m + memory: 1Mi sessionAgent: # Specifies the Airlock Microgateway Session Agent image. image: # -- Image repository from which to pull the Airlock Microgateway Session Agent image. repository: "quay.io/airlock/microgateway-session-agent" # -- Image tag to pull. - tag: "4.3.4" + tag: "4.4.0" # -- SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). # Overrides tag when specified. - digest: "sha256:df4e50d0929cb4c5e4486452979b59ec17f5e49a1516b685acd3a1ab0ddb3cf4" + digest: "sha256:fbb90f2a52bb1b19cca6c5c133e80331153c019ec905db052c250fedbb09c3bc" # -- Pull policy for this image. pullPolicy: IfNotPresent # -- Resource restrictions to apply to the Airlock Microgateway Session Agent container. @@ -205,6 +220,15 @@ dashboards: blockLogs: # -- Whether to create the block logs dashboard. create: true + headerLogs: + # -- Whether to create the header rewrite logs dashboard. + create: true + logOnlyMetrics: + # -- Whether to create the log only metrics dashboard + create: true + logOnlyLogs: + # -- Whether to create the log only logs dashboard. + create: true # Check whether the installation of the Airlock Microgateway Helm Chart was successful. # Requires a secret with a valid Airlock Microgateway license key already to be present. tests: diff --git a/examples/README.md b/examples/README.md index f34c035..3afdc38 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,4 +1,2 @@ # Description -The following folders contain example configurations and utility manifest files. This should help to get started with Airlock Microgateway. -* `configurations`: Folder that contains examples on how to protect an application with Airlock Microgateway. -* `utilities`: Contains utility manifests, like backends and prerequisites for the Airlock Microgateway Operator Deployment. \ No newline at end of file +The following folders contain example configurations. This should help to get started with Airlock Microgateway. \ No newline at end of file diff --git a/examples/configurations/basic/README.md b/examples/configurations/basic/README.md deleted file mode 100644 index ad40588..0000000 --- a/examples/configurations/basic/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Description -This folder contains the most basic example to get started with an almost empty `SidecarGateway` CR that will protect the `nginx` backend. The backend is defined in `examples/utilities/backends/nginx-protected`. - -* Execute - ``` - kubectl apply -k https://github.com/airlock/microgateway/examples/configurations/basic/ - ``` - to deploy the application. - - -* Perform a test call - - *Request* - ``` - kubectl run test-caller --image=curlimages/curl --rm --restart=Never -i --tty --command -- curl -v "http://nginx:8080/" - ``` - - *Output* - ``` - - - - Welcome to nginx! - - - -

Welcome to nginx!

-

If you see this page, the nginx web server is successfully installed and - working. Further configuration is required.

- -

For online documentation and support please refer to - nginx.org.
- Commercial support is available at - nginx.com.

- -

Thank you for using nginx.

- - - ``` \ No newline at end of file diff --git a/examples/configurations/basic/kustomization.yaml b/examples/configurations/basic/kustomization.yaml deleted file mode 100644 index 1737f3f..0000000 --- a/examples/configurations/basic/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - ../../utilities/backends/nginx-protected - - sidecargateway.yaml diff --git a/examples/configurations/basic/sidecargateway.yaml b/examples/configurations/basic/sidecargateway.yaml deleted file mode 100644 index 5138779..0000000 --- a/examples/configurations/basic/sidecargateway.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: SidecarGateway -metadata: - name: basic -spec: - podSelector: - matchLabels: - app: nginx - applications: - - containerPort: 8080 \ No newline at end of file diff --git a/examples/configurations/policy/README.md b/examples/configurations/policy/README.md deleted file mode 100644 index 52c77f8..0000000 --- a/examples/configurations/policy/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Description -There are different tools available to enforce policies for Kubernetes resources. The most famous ones are Open Policy Agent Gatekeeper, Kyverno or Kubewarden. They allow enforcing constraints on Kubernetes resources which includes the Microgateway CRDs. - -Basically, the mentioned tools do the same but in detail, they differ in their policy language, Kubernetes-native integration, possibility to use outside Kubernetes, and integration in CI/CD pipeline. This is why you should check which of them suits best for you and whether you use already one of them. - -## Examples -### Prerequisites -1. Install the Kyverno operator as described in [utilities/kyverno](/examples/utilities/kyverno/README.md). - -2. Apply the Kyverno policy: -``` -kubectl apply -k https://github.com/airlock/microgateway/examples/configurations/policy -``` - - -### Allowed Example -The following example shows a policy with Kyverno which allows secure deny rules settings. - -``` -kubectl apply -k https://github.com/airlock/microgateway/examples/configurations/policy/allowed -``` - -Output -``` -denyrules.microgateway.airlock.com/denyrule1-ok created -denyrules.microgateway.airlock.com/denyrule2-ok created -``` - -### Denied Example -This following example shows a policy with Kyverno which denies insecure deny rules settings. - -``` -kubectl apply -k https://github.com/airlock/microgateway/examples/configurations/policy/denied -``` - -Output -``` -Error from server: error when creating "https://github.com/airlock/microgateway/examples/configurations/policy/denied/denyrules-1.yaml": admission webhook "validate.kyverno.svc-fail" denied the request: - -resource DenyRules/default/denyrule1-nok was blocked due to the following policies - -disallow-insecure-denyrules: - disallow-insecure-threatHandlingMode: 'DenyRules with ''threatHandlingMode'' other - than ''Block'' is not allowed. ' - -Error from server: error when creating "https://github.com/airlock/microgateway/examples/configurations/policy/denied/denyrules-2.yaml": admission webhook "validate.kyverno.svc-fail" denied the request: - -resource DenyRules/default/denyrule2-nok was blocked due to the following policies - -disallow-insecure-denyrules: - disallow-denyRules-with-insecure-security-level: 'DenyRules with ''level'' other - than ''Standard'' or ''Strict'' is not allowed. ' - -``` - -For detailed information consult the [documentation](https://docs.airlock.com/microgateway/nightly/#data/1668421866273.html). \ No newline at end of file diff --git a/examples/configurations/policy/allowed/denyrules-1.yaml b/examples/configurations/policy/allowed/denyrules-1.yaml deleted file mode 100644 index 199ff75..0000000 --- a/examples/configurations/policy/allowed/denyrules-1.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: DenyRules -metadata: - annotations: - name: denyrule1-ok -spec: - request: - builtIn: - settings: - level: Strict - threatHandlingMode: Block diff --git a/examples/configurations/policy/allowed/denyrules-2.yaml b/examples/configurations/policy/allowed/denyrules-2.yaml deleted file mode 100644 index 7f9088a..0000000 --- a/examples/configurations/policy/allowed/denyrules-2.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: DenyRules -metadata: - annotations: - name: denyrule2-ok -spec: - request: - builtIn: - settings: - threatHandlingMode: Block diff --git a/examples/configurations/policy/allowed/kustomization.yaml b/examples/configurations/policy/allowed/kustomization.yaml deleted file mode 100644 index f315f93..0000000 --- a/examples/configurations/policy/allowed/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - denyrules-1.yaml - - denyrules-2.yaml diff --git a/examples/configurations/policy/denied/denyrules-1.yaml b/examples/configurations/policy/denied/denyrules-1.yaml deleted file mode 100644 index fb8f1a0..0000000 --- a/examples/configurations/policy/denied/denyrules-1.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: DenyRules -metadata: - annotations: - name: denyrule1-nok -spec: - request: - builtIn: - settings: - level: Strict - threatHandlingMode: LogOnly diff --git a/examples/configurations/policy/denied/denyrules-2.yaml b/examples/configurations/policy/denied/denyrules-2.yaml deleted file mode 100644 index 488b498..0000000 --- a/examples/configurations/policy/denied/denyrules-2.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: DenyRules -metadata: - annotations: - name: denyrule2-nok -spec: - request: - builtIn: - settings: - level: Basic - threatHandlingMode: Block diff --git a/examples/configurations/policy/denied/kustomization.yaml b/examples/configurations/policy/denied/kustomization.yaml deleted file mode 100644 index f315f93..0000000 --- a/examples/configurations/policy/denied/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - denyrules-1.yaml - - denyrules-2.yaml diff --git a/examples/configurations/policy/kustomization.yaml b/examples/configurations/policy/kustomization.yaml deleted file mode 100644 index 5ab8995..0000000 --- a/examples/configurations/policy/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - kyverno-policy.yaml diff --git a/examples/configurations/policy/kyverno-policy.yaml b/examples/configurations/policy/kyverno-policy.yaml deleted file mode 100644 index 6acc2ca..0000000 --- a/examples/configurations/policy/kyverno-policy.yaml +++ /dev/null @@ -1,62 +0,0 @@ -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: disallow-insecure-denyrules - annotations: - policies.kyverno.io/title: Disallow insecure DenyRules - policies.kyverno.io/category: Security - policies.kyverno.io/severity: high - kyverno.io/kyverno-version: 1.6.0 - policies.kyverno.io/minversion: 1.6.0 - kyverno.io/kubernetes-version: "1.20" - policies.kyverno.io/subject: DenyRules - policies.kyverno.io/description: >- - Description: Disallow insecure DenyRules settings for 'threatHandlingMode', security 'level', ... - Contact: security@company.com -spec: - validationFailureAction: Enforce - background: true - rules: - - name: disallow-insecure-threatHandlingMode - match: - any: - - resources: - kinds: - - microgateway.airlock.com/v1alpha1/DenyRules - preconditions: - all: - - key: "{{ request.operation || 'BACKGROUND' }}" - operator: NotEquals - value: DELETE - validate: - message: >- - DenyRules with 'threatHandlingMode' other than 'Block' is not allowed. - deny: - conditions: - all: - - key: "{{ request.object.spec.request.builtIn.settings.threatHandlingMode }}" - operator: AnyNotIn - value: - - Block - - name: disallow-denyRules-with-insecure-security-level - match: - any: - - resources: - kinds: - - microgateway.airlock.com/v1alpha1/DenyRules - preconditions: - all: - - key: "{{ request.operation || 'BACKGROUND' }}" - operator: NotEquals - value: DELETE - validate: - message: >- - DenyRules with 'level' other than 'Standard' or 'Strict' is not allowed. - deny: - conditions: - all: - - key: "{{ request.object.spec.request.builtIn.settings.level }}" - operator: AnyNotIn - value: - - Standard - - Strict diff --git a/examples/configurations/templating/README.md b/examples/configurations/templating/README.md deleted file mode 100644 index b780540..0000000 --- a/examples/configurations/templating/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Description -This folder contains example manifest files to be used with kustomize for the templating use-case. With this use-case one defines a base template (analogous to the `templates` folder) that contains the base configuration, -which can be reused by a varity of application deployments. To override configuration elements of the template, apply a kustomization manifest file on top of the template (See [kustomize](https://kustomize.io/) for more information). -The folder `templates` contains the template manifest files that are referenced in the `kustomization.yaml` file which applies various patches to the resources. Instead of a folder it is possible to reference a git repository which contains the templates. To use a remote target change the `resources` in the kustomization file as follows: - -local folder -```yaml -resources: - - templates -``` -remote target -```yaml -resources: - - https://github.com/your-organisation/repository/templates/ -``` - -For detailed information consult the [documentation](https://docs.airlock.com/microgateway/latest/#data/1668421864983.html). \ No newline at end of file diff --git a/examples/configurations/templating/kustomization.yaml b/examples/configurations/templating/kustomization.yaml deleted file mode 100644 index 3c7b7a3..0000000 --- a/examples/configurations/templating/kustomization.yaml +++ /dev/null @@ -1,79 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - templates - -commonAnnotations: - mycompany.com/owner: "Project X" - mycompany.com/contact: "+41 00 123 45 67" - -commonLabels: - app.kubernetes.io/name: my-application - app.kubernetes.io/part-of: my-application-i-belong-too - -patchesJSON6902: - - target: - group: microgateway.airlock.com - version: v1alpha1 - kind: SidecarGateway - name: template - patch: |- - - op: replace - path: /metadata/name - value: my-app - - op: replace - path: /spec/podSelector/matchLabels/app - value: my-app-label - - op: replace - path: /spec/applications - value: - - containerPort: 8080 - routes: - - pathPrefix: / - secured: - contentSecurityRef: - name: my-app - - target: - group: microgateway.airlock.com - version: v1alpha1 - kind: ContentSecurity - name: template - patch: |- - - op: replace - path: /metadata/name - value: my-app - - op: replace - path: /spec/filter/denyRulesRef/name - value: my-app - - op: replace - path: /spec/headerRewritesRef/name - value: my-app - - target: - group: microgateway.airlock.com - version: v1alpha1 - kind: DenyRules - name: template - patch: |- - - op: replace - path: /metadata/name - value: my-app - - op: add - path: /spec/request/builtIn/exceptions - value: - - blockedData: - header: - name: - matcher: - exact: User-Agent - ruleKeys: - - XSS - - target: - group: microgateway.airlock.com - version: v1alpha1 - kind: HeaderRewrites - name: template - patch: |- - - op: replace - path: /metadata/name - value: my-app \ No newline at end of file diff --git a/examples/configurations/templating/templates/contentsecurity.yaml b/examples/configurations/templating/templates/contentsecurity.yaml deleted file mode 100644 index 49160be..0000000 --- a/examples/configurations/templating/templates/contentsecurity.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: ContentSecurity -metadata: - name: template -spec: - filter: - denyRulesRef: - name: template - headerRewritesRef: - name: template \ No newline at end of file diff --git a/examples/configurations/templating/templates/denyrules.yaml b/examples/configurations/templating/templates/denyrules.yaml deleted file mode 100644 index bccaaec..0000000 --- a/examples/configurations/templating/templates/denyrules.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: DenyRules -metadata: - name: template -spec: - request: - builtIn: - settings: - level: Standard - threatHandlingMode: Block \ No newline at end of file diff --git a/examples/configurations/templating/templates/headerrewrites.yaml b/examples/configurations/templating/templates/headerrewrites.yaml deleted file mode 100644 index 96b0a60..0000000 --- a/examples/configurations/templating/templates/headerrewrites.yaml +++ /dev/null @@ -1,83 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: HeaderRewrites -metadata: - name: template -spec: - request: - allow: - matchingHeaders: - builtIn: - standardHeaders: true - custom: - - name: Allow additional request header - headers: - - name: - matcher: - exact: Accept-Auth - - name: - matcher: - exact: Depth - - name: - matcher: - exact: Destination - - name: - matcher: - exact: If - - name: - matcher: - exact: Lock-Token - - name: - matcher: - exact: Overwrite - - name: - matcher: - exact: Timeout - - name: - matcher: - exact: translate - - name: - matcher: - exact: X-FeatureVersion - - name: - matcher: - exact: X-IDCRL_ACCEPTED - - name: - matcher: - exact: X-IDCRL_OPTIONS - - name: - matcher: - exact: X-MSGETWEBURL - - name: - matcher: - exact: X-MS-CookieUri-Requested - - name: - matcher: - exact: X-Office-Major-Version - - name: - matcher: - exact: Content-Length - remove: - builtIn: - alternativeForwardedHeaders: true - response: - add: - builtIn: - csp: true - featurePolicy: true - permissionsPolicy: true - hsts: true - hstsPreload: false - referrerPolicy: true - xContentTypeOptions: true - xFrameOptions: true - allow: - matchingHeaders: - builtIn: - standardHeaders: false - remove: - builtIn: - auth: - basic: false - negotiate: true - ntlm: true - permissiveCors: true \ No newline at end of file diff --git a/examples/configurations/templating/templates/kustomization.yaml b/examples/configurations/templating/templates/kustomization.yaml deleted file mode 100644 index 1f43e61..0000000 --- a/examples/configurations/templating/templates/kustomization.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - sidecargateway.yaml - - contentsecurity.yaml - - headerrewrites.yaml - - denyrules.yaml - -commonLabels: - app.kubernetes.io/template-version: 1.0.1 - app.kubernetes.io/version: 4.0.0 - app.kubernetes.io/component: airlock-microgateway \ No newline at end of file diff --git a/examples/configurations/templating/templates/sidecargateway.yaml b/examples/configurations/templating/templates/sidecargateway.yaml deleted file mode 100644 index 311d8a9..0000000 --- a/examples/configurations/templating/templates/sidecargateway.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: microgateway.airlock.com/v1alpha1 -kind: SidecarGateway -metadata: - name: template -spec: - podSelector: - matchLabels: - app: - applications: - - containerPort: - routes: - - pathPrefix: / - secured: - contentSecurityRef: - name: template \ No newline at end of file diff --git a/examples/gateway-api/conformance/conformance.md b/examples/gateway-api/conformance/conformance.md new file mode 100644 index 0000000..517af1c --- /dev/null +++ b/examples/gateway-api/conformance/conformance.md @@ -0,0 +1,53 @@ +# Gateway API conformance of Airlock Microgateway + +## Prerequisites +* [Airlock Microgateway License](#obtain-airlock-microgateway-license) +* [cert-manager](https://cert-manager.io/) +* [helm](https://helm.sh/docs/intro/install/) (>= v3.8.0) + +In order to use Airlock Microgateway you need a license and the cert-manager. You may either request a community license free of charge or purchase a premium license. +For an easy start in non-production environments, you may deploy the same cert-manager we are using internally for testing. +### Obtain Airlock Microgateway License +1. Either request a community or premium license + * Community license: [airlock.com/microgateway-community](https://airlock.com/en/microgateway-community) + * Premium license: [airlock.com/microgateway-premium](https://airlock.com/en/microgateway-premium) +2. Check your inbox and save the license file microgateway-license.txt locally. + +> See [Community vs. Premium editions in detail](https://docs.airlock.com/microgateway/latest/#data/1675772882054.html) to choose the right license type. +### Deploy cert-manager +```bash +helm repo add jetstack https://charts.jetstack.io +helm install cert-manager jetstack/cert-manager --version 'v1.16.1' -n cert-manager --create-namespace --set crds.enabled=true --wait +``` + +## Deploy Airlock Microgateway Operator + +> This guide assumes a microgateway-license.txt file is present in the working directory. + +1. Install CRDs and Operator. + ```bash + # Create namespace + kubectl create namespace airlock-microgateway-system + + # Install License + kubectl -n airlock-microgateway-system create secret generic airlock-microgateway-license --from-file=microgateway-license.txt + + # Install the operator and activate the Gateway API support. + helm install -n airlock-microgateway-system airlock-microgateway oci://quay.io/airlockcharts/microgateway --wait --version '4.4.0' --set=operator.gatewayAPI.enabled=true + ``` + +2. Verify that the operator started successfully: + ```bash + kubectl -n airlock-microgateway-system wait --for=condition=Available deployments --all --timeout=3m + ``` + +3. Deploy manifests (GatewayClass, ServiceAccount and ClusterRoleBinding) and run Job to generate report + ```bash + kubectl apply -f manifests/conformance-report.yaml + ``` + +4. After running, see the conformance report: + ```bash + kubectl logs jobs/gateway-conformance-tests -f + ``` + diff --git a/examples/gateway-api/conformance/manifests/conformance-report.yaml b/examples/gateway-api/conformance/manifests/conformance-report.yaml new file mode 100644 index 0000000..4eefb08 --- /dev/null +++ b/examples/gateway-api/conformance/manifests/conformance-report.yaml @@ -0,0 +1,71 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: gateway-conformance +spec: + controllerName: microgateway.airlock.com/gatewayclass-controller +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: gateway-conformance-tests +spec: + template: + spec: + initContainers: + - name: git-checkout + image: bitnami/git:latest + command: + - sh + - -c + - | + cd /workspace + + git clone https://github.com/kubernetes-sigs/gateway-api.git --branch v1.1.0 + volumeMounts: + - name: workspace + mountPath: /workspace + containers: + - name: go-test + image: golang:1.23.2-alpine + command: + - sh + - -c + - | + cd /workspace/gateway-api + + go test ./conformance -run TestConformance -args \ + --supported-features=Gateway,GatewayPort8080,HTTPRoute,HTTPRouteBackendProtocolH2C,HTTPRouteBackendProtocolWebSocket,HTTPRouteDestinationPortMatching,HTTPRouteMethodMatching,HTTPRouteParentRefPort,HTTPRouteQueryParamMatching,ReferenceGrant \ + --organization=airlock --project=microgateway --url="https://github.com/airlock/microgateway" --version=v4.4.0 --contact="https://www.airlock.com/en/contact" \ + --conformance-profiles=GATEWAY-HTTP \ + --report-output=/workspace/conformance-profile.yaml + + cat /workspace/conformance-profile.yaml + volumeMounts: + - name: workspace + mountPath: /workspace + volumes: + - name: workspace + emptyDir: {} + serviceAccountName: gateway-conformance-tests + restartPolicy: Never + backoffLimit: 0 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: gateway-conformance-tests + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gateway-conformance-tests +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: + - kind: ServiceAccount + name: gateway-conformance-tests + namespace: default \ No newline at end of file diff --git a/examples/utilities/backends/README.md b/examples/utilities/backends/README.md deleted file mode 100644 index a318afb..0000000 --- a/examples/utilities/backends/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Description -This folder contains example backends which can be deployed and protected by Airlock Microgateway. - -The folder with the '-protected' suffix already contains the required Kubernetes annotation in order to be protected by Airlock Microgateway. -Please note that additional configuration like CustomResources SidecarGateway are required. Please consult the [documentation](https://docs.airlock.com/microgateway/latest/) for detailed instructions. diff --git a/examples/utilities/backends/nginx-protected/kustomization.yaml b/examples/utilities/backends/nginx-protected/kustomization.yaml deleted file mode 100644 index 6738404..0000000 --- a/examples/utilities/backends/nginx-protected/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -resources: - - ../nginx - -components: - - ../../../components/mgw-injection diff --git a/examples/utilities/backends/nginx/common.conf b/examples/utilities/backends/nginx/common.conf deleted file mode 100644 index 7eba9a8..0000000 --- a/examples/utilities/backends/nginx/common.conf +++ /dev/null @@ -1,15 +0,0 @@ -location / { - root /usr/share/nginx/html; - index index.html index.htm; - - # Serve index.html for all paths - try_files $uri /index.html; -} - -# Hack to allow POST on static pages -error_page 405 =200 $uri; - -error_page 500 502 503 504 /50x.html; -location = /50x.html { - root /usr/share/nginx/html; -} diff --git a/examples/utilities/backends/nginx/default.conf b/examples/utilities/backends/nginx/default.conf deleted file mode 100644 index 2422a19..0000000 --- a/examples/utilities/backends/nginx/default.conf +++ /dev/null @@ -1,7 +0,0 @@ -server { - listen 8080; - listen [::]:8080; - server_name localhost; - - include /etc/nginx/server.conf.d/*.conf; -} diff --git a/examples/utilities/backends/nginx/deployment.yaml b/examples/utilities/backends/nginx/deployment.yaml deleted file mode 100644 index 3ddfec3..0000000 --- a/examples/utilities/backends/nginx/deployment.yaml +++ /dev/null @@ -1,59 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: backend - name: nginx -spec: - replicas: 1 - selector: - matchLabels: - app: backend - template: - metadata: - labels: - app: backend - spec: - containers: - - image: nginxinc/nginx-unprivileged:1.23-alpine - name: nginx - ports: - - containerPort: 8080 - securityContext: - allowPrivilegeEscalation: false - privileged: false - runAsNonRoot: true - capabilities: - drop: [ "ALL" ] - readOnlyRootFilesystem: true - seccompProfile: - type: RuntimeDefault - volumeMounts: - - name: config-volume - mountPath: /etc/nginx/nginx.conf - subPath: nginx.conf - readOnly: true - - name: config-include-volume - mountPath: /etc/nginx/conf.d - readOnly: true - - name: server-config-include-volume - mountPath: /etc/nginx/server.conf.d - readOnly: true - - name: run - mountPath: /var/run/ - - name: tmp - mountPath: /tmp - volumes: - - name: config-volume - configMap: - name: nginx-config - - name: config-include-volume - configMap: - name: nginx-default-config - - name: server-config-include-volume - configMap: - name: nginx-server-config - - name: run - emptyDir: {} - - name: tmp - emptyDir: {} diff --git a/examples/utilities/backends/nginx/kustomization.yaml b/examples/utilities/backends/nginx/kustomization.yaml deleted file mode 100644 index 442520a..0000000 --- a/examples/utilities/backends/nginx/kustomization.yaml +++ /dev/null @@ -1,17 +0,0 @@ -resources: -- deployment.yaml -- service.yaml - -configMapGenerator: -- name: nginx-config - files: - - nginx.conf -- name: nginx-default-config - files: - - default.conf -- name: nginx-server-config - files: - - common.conf - -generatorOptions: - disableNameSuffixHash: true diff --git a/examples/utilities/backends/nginx/nginx.conf b/examples/utilities/backends/nginx/nginx.conf deleted file mode 100644 index c055a92..0000000 --- a/examples/utilities/backends/nginx/nginx.conf +++ /dev/null @@ -1,64 +0,0 @@ -# Patched Parts -# * error_log -# * access_log -# * http.log_format -worker_processes auto; - -error_log /dev/stderr debug; -pid /tmp/nginx.pid; - -events { - worker_connections 1024; -} - -http { - - log_format main escape=json '{' - '"timestamp": "$time_iso8601", ' - '"req_id": "$request_id", ' - '"upstream_status": "$upstream_status", ' - '"upstream_addr": "$upstream_addr", ' - '"http_req":{ ' - ' "http_method": "$request_method", ' - ' "entry_url": "$scheme://$host$request_uri", ' - ' "entry_path": "$request_uri", ' - ' "entry_query": "$query_string", ' - ' "http_status": $status, ' - ' "vhost_proto":"$scheme", ' - ' "vhost_proto_vers": "$server_protocol", ' - ' "http_user_agent": "$http_user_agent", ' - ' "http_referrer": "$http_referer", ' - ' "http_content_type": "$content_type", ' - ' "http_host": "$host", ' - ' "http_x_request_id": "$http_x_request_id", ' - ' "req_size": "$request_length", ' - ' "resp_size": "$upstream_response_length", ' - ' "time_resp": "$upstream_response_time s", ' - ' "client_ip": "$remote_addr", ' - ' "front_src_ip": "$http_x_forwarded_for", ' - ' "front_src_port": "$remote_port", ' - ' "front_dst_port": "$server_port", ' - ' "front_tls_proto": "$ssl_protocol", ' - ' "front_tls_cipher": "$ssl_cipher" ' - '}}'; - - proxy_temp_path /tmp/proxy_temp; - client_body_temp_path /tmp/client_temp; - fastcgi_temp_path /tmp/fastcgi_temp; - uwsgi_temp_path /tmp/uwsgi_temp; - scgi_temp_path /tmp/scgi_temp; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - access_log /dev/stdout main; - - sendfile on; - - keepalive_timeout 65; - - # Disable body size limit - client_max_body_size 0; - - include /etc/nginx/conf.d/*.conf; -} diff --git a/examples/utilities/backends/nginx/service.yaml b/examples/utilities/backends/nginx/service.yaml deleted file mode 100644 index 1de3fbf..0000000 --- a/examples/utilities/backends/nginx/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: backend - name: backend -spec: - ports: - - name: http - port: 8080 - protocol: TCP - selector: - app: backend - type: NodePort diff --git a/examples/utilities/kyverno/.gitignore b/examples/utilities/kyverno/.gitignore deleted file mode 100644 index 80bf7fc..0000000 --- a/examples/utilities/kyverno/.gitignore +++ /dev/null @@ -1 +0,0 @@ -charts \ No newline at end of file diff --git a/examples/utilities/kyverno/README.md b/examples/utilities/kyverno/README.md deleted file mode 100644 index 8a4b943..0000000 --- a/examples/utilities/kyverno/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Description -Airlock Microgateway can be used together with [kyverno](https://kyverno.io/). - -For an easy start in non-production environments, you may deploy the same kyverno operator we are using internally for testing. - -``` -helm repo add kyverno https://kyverno.github.io/kyverno/ -helm install kyverno kyverno/kyverno --version '3.2.5' -n kyverno --create-namespace --wait -f https://raw.githubusercontent.com/airlock/microgateway/main/examples/utilities/kyverno/values.yaml -``` diff --git a/examples/utilities/kyverno/values.yaml b/examples/utilities/kyverno/values.yaml deleted file mode 100644 index 3a1fe5c..0000000 --- a/examples/utilities/kyverno/values.yaml +++ /dev/null @@ -1,4 +0,0 @@ -config: - resourceFiltersExcludeNamespaces: - - "kube-system" - webhooks: null \ No newline at end of file