WASI
Regular policy authors should never use plain WASI system interfaces to write policies.
This page is meant to be used by Kubewarden maintainers/low level policy authors who want to experiment with bleeding edge WASM platforms.
Kubewarden WASI policies are supported starting from Kubewarden 1.7.0 release
WASI is a WebAssembly standard that provides a set of interfaces that allow the execution of WebAssembly outside of the browser.
Thanks to WASI, it's possible to have a WebAssembly module that interacts with system primitives like STDOUT, STDERR, STDIN, environment variables and more.
Actually, many of the compilers used to compile Kubewarden policies
produce WebAssembly modules that targets the WASI interfaces.
However, Kubewarden policies leverage the waPC
project to implement a bi-directional communication between the
policy and the policy runtime (kwctl
or policy-server
); this communication
protocol is described here.
There are however some special cases when the waPC project cannot be used yet. In these limited circumstances it's possible to write a policy just by using the interfaces provided by WASI.
Limitations​
WASI policies should not be used under regular circumstances because they suffer from the following limitations:
- No bi-directional communication, hence host capabilities are not available
- No context-aware capabilities
- Inferior performance at evaluation time compared to waPC/Rego based policies
Use cases​
The only reason to write a "plain WASI" policy is when the waPC communication mechanism cannot be leveraged.
Currently (as of June 2023), the only good reason to do that is when using the official Go compiler to produce a WebAssembly module.
Starting from the 1.21 release, the official Go compiler is able to produce WebAssembly modules targeting the WASI interface. However, these modules cannot yet export functions to the WebAssembly runtime. This limitation, tracked by this dedicated issue, prevents the adoption of the waPC protocol.
Generally speaking, we advice to write Kubewarden Go policies using the TinyGo compiler, as described here.
However, some complex Go code bases cannot be compiled using the TinyGo compiler. This includes, for example, code bases like CEL-go or kyverno. In these circumstances, the usage of the official Go compiler can be beneficial.
Communication protocol​
This section describes how to write a plain WASI policy.
The code has to be written as a regular CLI program. The program must take the following subcommands:
validate
: this command is invoked by the policy engine to evaluate an admission requestvalidate-settings
: this command is invoked by the policy engine to validate the policy settings
In both cases, the data to be validated is provided via the STDIN. The policy must provide the answer via the STDOUT. The STDERR can be used to provide debug or error messages.
Validation​
The validation of a request is done when the policy CLI program is invoked using
the validate
subcommand.
The STDIN must contain a JSON document describing a ValidationRequest
object.
The policy must to write to the STDOUT a JSON document that contains a
ValidationResponse
object.
Both the ValidationRequest
and ValidationResponse
objects are described
here.
Mutation​
Mutating policies work in the same way as validating ones. The policy CLI program
is invoked using the validate
subcommand.
The STDIN must contain a JSON document describing a ValidationRequest
object.
The policy must to write to the STDOUT a JSON document that contains a
ValidationResponse
object.
Both the ValidationRequest
and ValidationResponse
objects are described
here.
When a mutation has to be done, the ValidationResponse
object must have a
key mutated_object
that contains the object that has to be created.
This is described here.
Settings validation​
The policy must provide a subcommand named validate-settings
. This command
is used to validate the settings that have been provided by the user.
The program must receive on the STDIN a JSON object that holds the settings
provided by the user.
It will then validate them and write a SettingsValidationResponse
object
to the STDOUT.
The format of the SettingsValidationResponse
and the settings validation
process is described here.
Policy metadata​
Each Kubewarden policy must be annotated via the kwctl annotate
command.
The policy metadata of a plain WASI policy must provide this value:
executionMode: wasi
Template project​
This GitHub repository contains a template of a Go-based policy that leverages the WASI protocol.