jsPolicy
website·Indexed 33 days ago
https://www.jspolicy.com/docs/A policy engine for Kubernetes that allows developers to write validating and mutating policies using JavaScript or TypeScript. It provides a set of built-in functions for cluster interaction, such as create(), update(), remove(), and mutate(), and can be installed via Helm v3.
What's inside jsPolicy
- jsPolicy is a policy engine for Kubernetes that enables developers to write policies using JavaScript or TypeScript. It leverages Google's V8 engine with pre-heated sandbox environments for high-performance execution, typically completing most policies in under one millisecond. It supports the use of any CommonJS JavaScript or TypeScript libraries from npm or private registries.
Overview of jsPolicy Architecture
jsPolicy is a Kubernetes policy engine that allows users to write policies in JavaScript or TypeScript. It operates as a single container consisting of three logical components: the Webhook Manager, the V8 JavaScript Sandbox Pool, and the Policy Compiler.Overview of jsPolicy logic implementation workflows
jsPolicy provides three primary workflows for implementing policy logic. The choice depends on the required level of type safety, IDE support, and testing capabilities.Feature Embedded spec.javascript Separate JavaScript TypeScript Language JavaScript JavaScript TypeScript (modern) Type Safety No No Yes IDE Support Bad (JS in YAML) Good Great Testing End-to-end only Unit, Functional, E2E Unit, Functional, E2E Publishing Via JsPolicy YAML Via npm packages Via npm packages Bundle Gen Automatic Manual/SDK Manual/SDK SDK N/A jsPolicy SDK jsPolicy SDK jsPolicy Features and Capabilities
jsPolicy is a Kubernetes policy engine with the following capabilities:
- Language Support: Policies are written in JavaScript or TypeScript (or any language that compiles to JS).
- Validating Policies: Supports standard validating admission control policies.
- Mutating Policies: Provides a streamlined way to write mutating admission control policies.
- Controller Policies: Supports policies executed after Events in the cluster (a unique feature not found in OPA or Kyverno).
- Tooling: Integrates with the standard JavaScript ecosystem for development, testing, and maintenance.
- Package Management: Policies and policy functions can be published and shared via npm (npmjs.com) or private npm registries.
Understand the JsPolicyViolations CRD structure
TheJsPolicyViolationsCustom Resource Definition (CRD) in thepolicy.jspolicy.com/v1beta1API group is used to report policy violations. It captures details about the denied action, the specific reason for the violation, the request information (including the target resource and operation), and the user identity associated with the request.apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicyViolations metadata: name: "policy-name.company.tld" status: violations: - action: "deny" code: 500 message: "Namespace 'default' not allowed!" reason: "namespace_disallowed" requestInfo: operation: "" apiVersion: "v1" kind: "Pod" name: "nginx" namespace: "default" userInfo: uid: "uid" username: "admin" timestamp: "2021-05-05T00:32:02Z"Access requesting user information
The
userInfoobject contains details about the user making the request:username: The unique identifier for the user among all active users.uid: A unique value identifying the user across time (persists even if a user is deleted and recreated with the same name).groups: A list of groups the user belongs to.extra: Additional information provided by the authenticator.
Understand jsPolicy policy types
jsPolicy provides three types of policies to govern Kubernetes clusters:
- Mutating Policies: Triggered by requests to the k8s API server. They run sequentially and are expected to call
mutate()on the request object. - Validating Policies: Triggered by requests to the k8s API server. They run in parallel after mutating policies. If any validating policy calls
deny(), the request is aborted and not persisted in etcd. - Controller Policies: Triggered asynchronously by Kubernetes Events (CRUD operations). They are queued and can perform any action, including executing other CRUD operations in the cluster.
Additionally, Mutating and Validating policies can use
warn()to send warnings to the client (e.g., visible inkubectloutput) without blocking the request.- Mutating Policies: Triggered by requests to the k8s API server. They run sequentially and are expected to call
Compare jsPolicy policy types
jsPolicy provides three distinct policy types based on when they are triggered and their intended outcome:
Type Trigger Execution Order Expected Result Mutating Requests to k8s API server Sequential Modified request object via mutate()Validating Requests to k8s API server Parallel allow()ordeny()the requestController Changes to k8s objects (Events) Queued Any action/side-effect Mutating and Validating policies run during the HTTP request to the Kubernetes API server after authentication and RBAC. Mutating policies run first (sequentially), followed by Validating policies (in parallel). If any Validating policy calls
deny(), the request is aborted and not persisted in etcd.Use Mutating policies to modify Kubernetes objects
Mutating policies are used to change the payload of a Kubernetes object during a request (e.g., via
kubectl). They are executed sequentially after RBAC to prevent interference between multiple mutations.Common use cases include:
- Adding mandatory labels or annotations to metadata.
- Auto-completing fields (e.g., adding a
nodeSelectorto a Pod). - Replacing placeholders in resource definitions (e.g., replacing
#BASE_HOSTNAME#with a real domain in an Ingress).
Reinvocation Policy: You can configure
reinvocationPolicyto determine if the policy should be called again if other admission plugins modify the object:Never(Default): The webhook is called only once per admission evaluation.IfNeeded: The webhook may be called again if the object is modified by other plugins after the initial call.
Import npm dependencies into a JsPolicy
Use the
importstatement within thejavascriptblock of aJsPolicyto use external libraries. Dependencies must be declared in thespec.dependenciessection of the policy manifest using the same syntax as apackage.jsonfile. JsPolicy automatically runsnpm installand uses webpack to bundle and minify the dependencies and the policy payload into a singleJsPolicyBundlein the cluster.To import packages from private npm registries, you must overwrite the
~/.npmrcfile within the jspolicy container.apiVersion: policy.jspolicy.com/v1beta1 kind: JsPolicy metadata: name: "dependency-policy.example.com" spec: operations: ["CREATE"] resources: ["pods"] # Declare dependencies like in package.json dependencies: lodash: "^4.17.21" javascript: | import _ from 'lodash'; // Use the imported library in the policy logic if (_.isEqual(request.object.metadata?.labels, {"my-forbidden-label": "my-forbbiden-value"})) { deny("forbidden label set encountered"); }Delete jsPolicy Custom Resource Definitions (CRDs)
To remove all jsPolicy CRDs and their associated resources (such asJsPolicy,JsPolicyBundle, andJsPolicyViolationsobjects), use the following command. Warning: This action results in the permanent loss of all jsPolicy objects in the cluster.kubectl api-resources --api-group='policy.jspolicy.com' -o name | xargs kubectl delete crdShare jsPolicy policies via Kubernetes YAML
Policy authors can share policies for others to use in Kubernetes by providing YAML files. There are two primary distribution methods:
- Share a standalone
JsPolicyYAML file for direct application. - Share a combination of a
JsPolicyand aJsPolicyBundleYAML file to provide both the policy definition and its associated bundle.
# Apply a single policy kubectl apply -f policy.yaml # Apply a policy and its bundle kubectl apply -f policy.bundle.yaml -f policy.yaml- Share a standalone