Skip to content

Commit

Permalink
docs: update vap doc and demo (#3502)
Browse files Browse the repository at this point in the history
Signed-off-by: Rita Zhang <[email protected]>
Co-authored-by: Jaydipkumar Arvindbhai Gabani <[email protected]>
  • Loading branch information
ritazh and JaydipGabani authored Aug 20, 2024
1 parent 4eb7dcd commit 28bb1b1
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 31 deletions.
7 changes: 4 additions & 3 deletions demo/k8s-validating-admission-policy/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
> [!WARNING]
> This is a demo of an alpha feature and is subject to change.
> This is a demo of an alpha and a beta feature and is subject to change.
This demo shows two new capabilities:
1. Together with Gatekeeper and gator CLI, you can get admission, audit, and shift left validations for both CEL-based Validating Admission Policy and OPA Rego policies, even for clusters that do not support Kubernetes Validating Admission Policy feature yet.
1. Gatekeeper can be enabled to generate Kubernetes Validating Admission Policy resources such that admission validation can be handled by [Kubernetes's in-process Validating Admission Policy Controller](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/) instead of the Gatekeeper admission webhook. In the event the Validating Admission Policy Controller fails open, then Gatekeeper admission webhook can act as a fallback. This requires clusters with the Kubernetes Validating Admission Policy feature enabled.
1. [beta] Together with Gatekeeper and gator CLI, you can get admission, audit, and shift left validations for both Validating Admission Policy style CEL-based and OPA Rego policies, even for clusters that do not support Kubernetes Validating Admission Policy feature yet.
1. [alpha] Gatekeeper can be enabled to generate Kubernetes Validating Admission Policy and Binding resources such that admission validation can be handled by [Kubernetes's in-process Validating Admission Policy Controller](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/) instead of the Gatekeeper admission webhook. In the event the Validating Admission Policy Controller fails open, then Gatekeeper admission webhook can act as a fallback. This requires clusters with the Kubernetes Validating Admission Policy feature enabled.

Please refer to https://open-policy-agent.github.io/gatekeeper/website/docs/next/validating-admission-policy for pre-requisites and configuration steps.

Expand Down
Binary file modified demo/k8s-validating-admission-policy/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 12 additions & 6 deletions demo/k8s-validating-admission-policy/demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

clear

p "To ensure the ValidatingAdmissionPolicy feature is enabled for the cluster"
p "To ensure the ValidatingAdmissionPolicy feature is available for the cluster"

pe "kubectl api-resources | grep ValidatingAdmissionPolicy"

p "Deploy the constraint template"

pe "kubectl apply -f k8srequiredlabels_template.yaml"

p "View Constraint template to see a new engine and CEL rules are added"
p "View Constraint template to see the K8sNativeValidation engine and CEL rules are added"

pe "cat k8srequiredlabels_template.yaml"

Expand All @@ -24,15 +24,21 @@ p "Let's test the policy"

pe "kubectl create ns test"

p "Note the bad namespace was blocked by the Gatekeeper webhook as evaluated by the new CEL rules"
p "Note the namespace was blocked by the Gatekeeper webhook as evaluated by the new CEL rules"

p "Now let's update the constraint template to generate the ValidatingAdmissionPolicy resources"
p "Now let's see how the ValidatingAdmissionPolicy feature works. First, let's check the --default-create-vap-binding-for-constraints flag is set to true to ensure ValidatingAdmissionPolicyBinding resources can be generated"

pe "kubectl get deploy gatekeeper-controller-manager -n gatekeeper-system -oyaml | grep default-create-vap-binding-for-constraints"

p "Let's update the constraint template to generate the ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding resources"

pe "kubectl apply -f k8srequiredlabels_template_usevap.yaml"

pe "cat k8srequiredlabels_template_usevap.yaml"

p "Notice the "gatekeeper.sh/use-vap": "yes" label was added to the template to generate ValidatingAdmissionPolicy resources. Let's see what the generated resources look like"
p ""

p "Notice generateVAP: true is added to the source part of the constraint template to generate ValidatingAdmissionPolicy resources. And since --default-create-vap-binding-for-constraints is set to true, ValidatingAdmissionPolicyBinding is generated from the constraint resource. Let's see what the generated resources look like"

pe "kubectl get ValidatingAdmissionPolicy"

Expand All @@ -42,7 +48,7 @@ p "Let's test the policy"

pe "kubectl create ns test"

p "Note the bad namespace was blocked by the ValidatingAdmissionPolicy admission controller"
p "Note the namespace was blocked by the ValidatingAdmissionPolicy admission controller"

p "THE END"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ spec:
- engine: K8sNativeValidation
source:
validations:
- expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))'
- expression: '(has(variables.anyObject.metadata) && variables.params.labels.all(entry, has(variables.anyObject.metadata.labels) && entry.key in variables.anyObject.metadata.labels))'
messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")'
- expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))'
- expression: '(has(variables.anyObject.metadata) && variables.params.labels.all(entry, has(variables.anyObject.metadata.labels) && entry.key in variables.anyObject.metadata.labels && string(variables.anyObject.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))'
message: "regex mismatch"
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
labels:
"gatekeeper.sh/use-vap": "yes"
spec:
crd:
spec:
Expand All @@ -30,8 +28,9 @@ spec:
code:
- engine: K8sNativeValidation
source:
generateVAP: true
validations:
- expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))'
- expression: '(has(variables.anyObject.metadata) && variables.params.labels.all(entry, has(variables.anyObject.metadata.labels) && entry.key in variables.anyObject.metadata.labels))'
messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")'
- expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))'
- expression: '(has(variables.anyObject.metadata) && variables.params.labels.all(entry, has(variables.anyObject.metadata.labels) && entry.key in variables.anyObject.metadata.labels && string(variables.anyObject.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))'
message: "regex mismatch"
33 changes: 17 additions & 16 deletions website/docs/validating-admission-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ id: validating-admission-policy
title: Integration with Kubernetes Validating Admission Policy
---

CEL validation in Gatekeeper:
Validating Admission Policy CEL validation in Gatekeeper:
Feature State: Gatekeeper version v3.17 (beta)
❗ This feature is beta, subject to change (feedback is welcome!). It is enabled by default. Set --enable-k8s-native-validation=false` to disable evaluating CEL in constraint templates.
❗ This feature is beta, subject to change (feedback is welcome!). It is enabled by default. Set --enable-k8s-native-validation=false` to disable evaluating Validating Admission Policy CEL in constraint templates.

VAP management through Gatekeeper:
Feature State: Gatekeeper version v3.16 (alpha)
Expand All @@ -17,7 +17,7 @@ This feature allows Gatekeeper to integrate with Kubernetes Validating Admission

## Motivations

The Validating Admission Policy feature was introduced as an alpha feature to Kubernetes v1.26, beta in v1.28 (disabled by default), GA in v1.30 (enabled by default). Some of the benefits include:
The Kubernetes Validating Admission Policy feature was introduced as an alpha feature to Kubernetes v1.26, beta in v1.28 (disabled by default), GA in v1.30 (enabled by default). Some of the benefits include:
- in-tree/native in-process
- reduce admission request latency
- improve reliability and availability
Expand Down Expand Up @@ -46,9 +46,9 @@ Find out more about different [enforcement points](enforcement-points.md)

## Pre-requisites

- Requires minimum Gatekeeper v3.16.0
- Requires minimum Kubernetes v1.30, when the `Validating Admission Policy` feature GAed
- [optional] Kubernetes version v1.29, need to enable feature gate and runtime config as shown below:
- Requires minimum Gatekeeper v3.17.0 (Please refer to the v3.16.0 docs as flags have changed)
- Requires minimum Kubernetes v1.30, when the Kubernetes `Validating Admission Policy` feature GAed
- [optional] Kubernetes version v1.29, need to enable Kubernetes feature gate and runtime config as shown below:

```yaml
kind: Cluster
Expand All @@ -61,10 +61,10 @@ Find out more about different [enforcement points](enforcement-points.md)
## Get started
## Policy updates to add CEL
## Policy updates to add VAP CEL
To see how it works, check out this [demo](https://github.com/open-policy-agent/gatekeeper/tree/master/demo/k8s-validating-admission-policy)
Example `K8sRequiredLabels` constraint template using the `K8sNativeValidation` engine and CEL expressions that requires resources to contain specified labels with values matching provided regular expressions. A similar policy written in Rego can be seen [here](https://open-policy-agent.github.io/gatekeeper-library/website/validation/requiredlabels)
Example `K8sRequiredLabels` constraint template using the `K8sNativeValidation` engine and VAP CEL expressions that requires resources to contain specified labels with values matching provided regular expressions. A similar policy written in Rego can be seen [here](https://open-policy-agent.github.io/gatekeeper-library/website/validation/requiredlabels)

```yaml
apiVersion: templates.gatekeeper.sh/v1
Expand Down Expand Up @@ -106,15 +106,16 @@ spec:
...
```
With this new engine and source added to the constraint template, now Gatekeeper webhook, audit, and shift-left can validate resources with these new CEL-based rules.
With this new engine and source added to the constraint template, now Gatekeeper webhook, audit, and shift-left can validate resources with these new VAP CEL-based rules.
## Policy updates to generate Validating Admission Policy resources
## Policy updates to generate Validating Admission Policy and Binding resources
For some policies, you may want admission requests to be handled by the K8s Validating Admission Controller instead of the Gatekeeper admission webhook.
Gatekeeper is configured to generate K8s Validating Admission Policy (VAP) resources for all constraint templates globally if `--default-create-vap-for-templates=true` flag is set. This flag defaults to `false` at this time to not generate VAP resources by default.
The K8s Validating Admission Controller requires both the Validating Admission Policy (VAP) and Validating Admission Policy Binding (VAPB) resources to exist to enforce a policy. Gatekeeper can be configured to generate both of these resources. To generate VAP Bindings for all Constraints, ensure the Gatekeeper
`--default-create-vap-binding-for-constraint` flag is set to `true`. To generate VAP as part of all Constraint Templates with the VAP CEL engine `K8sNativeValidation`, ensure the Gatekeeper `--default-create-vap-for-templates=true` flag is set to `true`. By default both flags are set to `false` while the feature is still in alpha.

If you would like to override this flag's behavior for any constraint templates, you can set generateVAP explicitly on per constraint template level.
To override the `--default-create-vap-for-templates` flag's behavior for a constraint template, set `generateVAP` to `true` explicitly under the K8sNativeValidation engine's `source` in the constraint template.

```yaml
spec:
Expand All @@ -127,7 +128,7 @@ spec:
...
```

Gatekeeper determines the intended enforcement actions for a given enforcement point by evaluating what is provided in `spec.scopedEnforcementActions` and `spec.enforcementAction: scoped` in the constraint. If these values are not provided in the constraint, then Gatekeeper will follow behavior defined by the flag `--default-create-vap-binding-for-constraints`. By default, `--default-create-vap-binding-for-constraints` is set to `false`.
To override the `--default-create-vap-binding-for-constraints` flag's behavior for a constraint, `spec.scopedEnforcementAction` can be used. Gatekeeper determines the intended enforcement actions for a given enforcement point by evaluating what is provided in `spec.scopedEnforcementActions` and `spec.enforcementAction: scoped` in the constraint.

The overall opt-in/opt-out behavior for constraint to generate Validating Admission Policy Binding (VAPB) is as below:

Expand All @@ -138,22 +139,22 @@ Constraint with `enforcementAction: scoped`:
| Not included | Do not generate VAPB |
| Included | Generate VAPB |

Constraint with `enforcementAction != scoped`:
Constraint without `enforcementAction: scoped`:

| `--default-create-vap-binding-for-constraints` | generate VAPB |
|----------|----------|
| false | Do not generate VAPB |
| true | Generate VAPB |

:::note
VAP will only get generated for templates with CEL Engine. VAPB will only get generated for constraints that belong to templates with CEL engine.
VAP will only get generated for templates with VAP CEL Engine. VAPB will only get generated for constraints that belong to templates with VAP CEL engine.
:::

:::tip
In the event K8s Validating Admission Controller fails open, Gatekeeper admission webhook can act as a backup when included in constraint.
:::

Validating Admission Policy Binding for the below constraint will always get generated, assuming the constraint belongs to a template with CEL engine.
Validating Admission Policy Binding for the below constraint will always get generated, assuming the constraint belongs to a template with VAP CEL engine.

```yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
Expand Down

0 comments on commit 28bb1b1

Please sign in to comment.