Documentation survey

This is unreleased documentation for Policy Manager 1.30-next.

Reusing ValidatingAdmissionPolicies

Kubernetes vanilla Validating policies consist of the following resources:

  • ValidatingAdmissionPolicy: describes the logic in CEL. It optionally accepts also parameters in spec.paramKind.

  • ValidatingAdmissionPolicyBinding: scopes the policy.

Let’s see a concrete example. These and others can be reused with Kubewarden’s cel-policy with little effort.

ValidatingAdmissionPolicy

The following ValidatingAdmissionPolicy is adapted from the Kubernetes docs.

This policy checks whether the number of Replicas in Deployments is less than or equal to a default maxreplicas of 5. Users can override this default per Namespace or Deployment and pick a smaller number via the use of a parameter.

It’s bound with a ValidatingAdmissionPolicyBinding. So, it only affects Namespaces that have a label environment set to test.

ValidatingAdmissionPolicy

./vap-policy-example.yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: "replicalimit-policy.example.com"
spec:
  failurePolicy: Fail # (1)
  matchConstraints: # (2)
    resourceRules:
      - apiGroups: ["apps"]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["deployments"]
  variables: # (3)
    - name: maxReplicas # hardcoded global default
      expression: int(5)
  paramKind: # (4)
    apiVersion: v1
    kind: ConfigMap # user-provided override
  validations: # (5)
    - expression: |
        object.spec.replicas <= (
          params.data.overrideReplicas != null && params.data.overrideReplicas < variables.maxReplicas
          ? params.data.overrideReplicas
          : variables.maxReplicas
        )
      messageExpression: |
        'The number of replicas must be less than or equal to ' +
        string(params.data.overrideReplicas != null && params.data.overrideReplicas < variables.maxReplicas
          ? params.data.overrideReplicas
          : variables.maxReplicas)
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "replicalimit-binding-test.example.com"
spec:
  policyName: "replicalimit-policy.example.com"
  validationActions: [Deny] # (7)
  matchResources: # (8)
    namespaceSelector:
      matchLabels:
        environment: test
  paramRef: # (4)
    name: "replica-limit-override"
    namespace: "test"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: replica-limit-override
  namespace: test
data:
  overrideReplicas: "3"

Here, we’ve an equivalent Kubewarden policy:

Kubewarden’s cel-policy

./cel-policy-example.yaml
apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
  annotations:
    io.kubewarden.policy.category: Resource validation # (9)
    io.kubewarden.policy.severity: low # (9)
  name: "cel-policy-replica-example"
spec:
  module: registry://ghcr.io/kubewarden/policies/cel-policy:v1.0.0
  failurePolicy: Fail # (6). Webhook behavior. Defaults to "Fail"
  mode: protect # (7). Defaults to "protect"
  rules: # (2)
    - apiGroups: ["apps"]
      apiVersions: ["v1"]
      operations: ["CREATE", "UPDATE"]
      resources: ["deployments"]
  settings:
    failurePolicy: Fail # (1). CEL behavior. Defaults to "Fail"
    variables: # (3)
      - name: "replicas"
        expression: "object.spec.replicas"
      - name: maxReplicas
        expression: int(5)
    paramKind: # (4)
      apiVersion: v1
      kind: ConfigMap # user-provided override
    paramRef: # (4)
      name: "replica-limit-override"
      namespace: "test"
    validations: # (5)
      - expression: |
          object.spec.replicas <= (
            params.data.overrideReplicas != null && params.data.overrideReplicas < variables.maxReplicas
            ? params.data.overrideReplicas
            : variables.maxReplicas
          )
        messageExpression: |
          'The number of replicas must be less than or equal to ' +
          string(params.data.overrideReplicas != null && params.data.overrideReplicas < variables.maxReplicas
            ? params.data.overrideReplicas
            : variables.maxReplicas)
  backgroundAudit: true # (9). Defaults to "true"
  namespaceSelector: # (8)
    matchLabels:
      environment: test
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: replica-limit-override
  namespace: test
data:
  overrideReplicas: "3"

Notice the commented numbers on both the YAML manifests. Let’s expand on them:

# VAP field cel-policy field Description

1

failurePolicy

settings.failurePolicy

CEL behavior, for when CEL expression evaluates to false, there’s CEL runtime errors, or there’s invalid or mis-configured CEL. For example, a CEL expression returning false, missing parameters, or missing variables. Not to confuse with (6).

2

matchConstraints

rules

Both accept the same RuleWithOperations that informs on what kind of Resource the policy applies to.

3

variables

settings.variables

In Kubewarden’s cel-policy, expressions that define variables are in settings.variables. Apart from that, they are equivalent.

4

paramKind,paramRef

settings.paramKind,settings.paramRef

In Kubewarden’s cel-policy, parameter definitions are in settings.paramKind, settings.paramRef. Apart from that, they are equivalent.

5

validations

settings.validations

In Kubewarden’s cel-policy, expressions that define validations are in settings.validations. Apart from that, they are equivalent.

6

---

failurePolicy

Webhook behavior, for Kubernetes API Webhook error or timeout, or for matchConditions evaluation. Not to confuse with (1).

7

validationActions

mode

mode has as options protect and monitor. Auditing is more full featured in Kubewarden, see (9).

8

matchResources

namespaceSelector, objectSelector

Define ways to constraint using Selectors. Kubewarden’s policies have them as namespaceSelector and objectSelector.

9

auditAnnotations (not pictured)

backgroundAudit, annotations

Use Kubewarden fields instead to set the policy usage in Audit Scanner, and its category and severity for PolicyReports.

matchConditions

matchConditions

Kubewarden’s policies have matchConditions (not pictured in this example).

---

Kubewarden-only features

For other features, see the rest of tutorial CEL examples.

You can use the kwctl tool to migrate a VAP policy to Kubewarden.

This VAP migration how-to describes how to do so.

Yet to be implemented equivalences

There are some VAP features that aren’t yet implemented. If you’re looking forward to them, please get in contact with us. These are:

Applying the policy

As usual, we can deploy our policy by instantiating its manifest:

$ kubectl apply -f ./cel-policy-example.yaml

And then test it by instantiating a deployment:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
  name: test
  labels:
    environment: test
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: test
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
EOF

namespace/test created
Error from server: error when creating "STDIN":
  admission webhook "clusterwide-cel-policy-replica-example.kubewarden.admission" denied the request:
  The number of replicas must be less than or equal to 5