Skip to content

Instantly share code, notes, and snippets.

@bjethwan
Last active July 13, 2020 15:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjethwan/1926c1b64c500986018823ce611d5808 to your computer and use it in GitHub Desktop.
Save bjethwan/1926c1b64c500986018823ce611d5808 to your computer and use it in GitHub Desktop.
Deploying both validating and mutating webhook configs together for open policy agent (OPA) policies

Example setup for making OPA work for both validating and mutating policies.

This would require two webhook (dynamic admission controller) configurations - MutatingWebhookConfiguration & ValidatingWebhookConfiguration

Replace the caBundle field below with ca cert you have used for generating certs for OPA.

Check the att in the path. It will be used later in the ConfigMap carrying OPA config.

kind: MutatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1beta1
metadata:
  name: opa-mutating-webhook
webhooks:
  - name: mutating.governance
    rules:
      - operations: ["*"]
        apiGroups: ["*"]
        apiVersions: ["*"]
        resources: ["*"]
    clientConfig:
      service:
        name: opa
        namespace: opa
        path: /v0/data/att/mutating
        port: 443
      caBundle: LS0
kind: ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1beta1
metadata:
  name: opa-validating-webhook
webhooks:
  - name: validating.governance
    rules:
      - operations: ["CREATE", "UPDATE"]
        apiGroups: ["*"]
        apiVersions: ["*"]
        resources: ["*"]
    clientConfig:
      service:
        namespace: opa
        name: opa
        path: /v0/data/att/validating
      caBundle: LS0
apiVersion: v1
kind: ConfigMap
metadata:
  name: opa-default-system-main
  namespace: opa
data:
  main.rego: |
    package att

    import data.kubernetes.admission

    mutating = {
        "apiVersion": "admission.k8s.io/v1beta1",
        "kind": "AdmissionReview",
        "response": {
            "allowed": true,

            # kube-apiserver only supports JSON Patch today.
            "patchType": "JSONPatch",

            # kube-apiserver expects changes to be represented as JSON Patch
            # operations against the resource. The JSON Patch must be JSON
            # serialized and base64 encoded.
            "patch": base64url.encode(json.marshal([
                {"op": "add", "path": "/metadata/annotations/foo", "value": "bar"},
            ])),
        }
    } {
        # Only apply mutations to objects in create/update operations (not
        # delete/connect operations.)
        is_create_or_update

        # If the resource has the "test-mutation" annotation key, the patch will be
        # generated and applied to the resource.
        input.request.object.metadata.annotations["test-mutation"]
    }

    is_create_or_update { is_create }
    is_create_or_update { is_update }
    is_create { input.request.operation == "CREATE" }
    is_update { input.request.operation == "UPDATE" }

    validating = {
      "apiVersion": "admission.k8s.io/v1beta1",
      "kind": "AdmissionReview",
      "response": response,
    }

    default response = {"allowed": true}

    response = {
        "allowed": false,
        "status": {
            "reason": reason,
        },
    } {
        reason = concat(", ", admission.deny)
        reason != ""
    }
  • kubectl create ns opa
  • kubectl label ns kube-system opa openpolicyagent.org/webhook=ignore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment