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)