This is the final post of the series.
Other parts:
I - Introduction
II - OPA Gatekeeper
III - Kyverno
jsPolicy offers a simple alternative to OPA. You can use it to write policy logic in JavaScript or TypeScript, and it offers Turing completeness, easy cluster access, and a huge ecosystem of libraries. Other features include validating, mutating, or changing policies, and defining controller policies. It uses Chrome V8 engine underneath, so performance and stability are battle tested
Installation
❯ helm install jspolicy jspolicy -n jspolicy --create-namespace --repo https://charts.loft.sh NAME: jspolicy LAST DEPLOYED: Tue Mar 8 20:46:34 2022 NAMESPACE: jspolicy STATUS: deployed ... ❯ kubectl get crds | grep jspolicy jspolicies.policy.jspolicy.com 2022-03-08T15:16:28Z jspolicybundles.policy.jspolicy.com 2022-03-08T15:16:28Z jspolicyviolations.policy.jspolicy.com 2022-03-08T15:16:28Z
Architecture
jsPolicy architecture from loft labs
Creating and instantiating policies
Validating policy to disallow workload creation under namespaces default
and restricted
❯ cat /tmp/policy.yaml # policy.yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "deny-default-namespace.example.com" spec: operations: ["CREATE"] resources: ["*"] scope: Namespaced javascript: | var namespacesToDeny = ["default", "restricted"]; if (namespacesToDeny.includes(request.namespace)) { deny("Creation of resources is not allowed in the following namespaces: " + namespacesToDeny.toString()); } ❯ kubectl create -f /tmp/policy.yaml jspolicy.policy.jspolicy.com/deny-default-namespace created
Mutating policy to add a foo=bar
label to pods
❯ cat /tmp/mutate.yaml apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "create-foo-bar-label.example.com" spec: type: Mutating operations: ["CREATE", "UPDATE"] resources: ["pods"] javascript: | if (request.object.metadata.labels?.["foo"] !== "bar") { request.object.metadata.labels = {...request.object.metadata.labels, 'foo': 'bar'}; // tell jspolicy to calc the patch and exit mutate(request.object); } ❯ kubectl create -f /tmp/mutate.yaml jspolicy.policy.jspolicy.com/create-foo-bar-label.example.com created ❯ kubectl run test-pod --image=nginx -n test-ns pod/test-pod created ❯ kubectl get pod -n test-ns --show-labels NAME READY STATUS RESTARTS AGE LABELS test-pod 1/1 Running 0 14s foo=bar,run=test-pod
Testing
❯ kubectl run test-pod --image=nginx --restart=Never Error from server (Forbidden): admission webhook "deny-default-namespace.example.com" denied the request: Creation of resources is not allowed in the following namespaces: default,restricted
Extra tools
Policies created for jsPolicy are regular javascript files =>
- You can develop policies with your favorite editor
- You can test(unit, functional, scale) with any javascript test frameworks like Jest, Mocha ..
- You can write policies as external JavaScript files and load them as a dependency This is a programming library so it can be scaled, evolved and maintained with relative ease over time.
More info
jsPolicy configuration
jsPolicy custom javascript functions
Comparison with OPA
I love the rationale(improve understandability) behind JSPolicy
Top comments (0)