seedwing-io / seedwing-policy

A functional type system for policy inspection, audit and enforcement.
https://www.seedwing.io
Apache License 2.0
12 stars 15 forks source link

feat: add initial static component executor #237

Open danbev opened 1 year ago

danbev commented 1 year ago

This commit adds a composed webassembly component model module that uses the policy engine module.

The idea here is that we can take a policy, perhaps created in the playground, and include it in the static component.


Example usage

To generate a .wasm module we specify a policy file and the policy name. We also have to specify a modules directory where the engine component, and the static-evaluator component are located:

$ wasm-generator -p policy.dog -n dog -m modules -o .
Created webassembly component: "working/target/static-config-component.wasm"
Composed into webassembly component:
"dog-composed.wasm"

With dog-composed.wasm we can then run it in a wasm runtime:

$ wasm-runtime -m dog-composed.wasm -i '{"name": "goodboy", "trained": true}'
"Ok: Because all fields were satisfied"

Sizes of component modules

$ cd engine/static-component
$ make show-component-sizes 
2.9M modules/seedwing-policy-engine-component.wasm
823K modules/static-evaluator-component.wasm
3.7M wasm-generator/working/target/dog-composed.wasm

Comments

I initially searched for a way to update a .wasm module with a policy which would have meant that we did not have to compile a new core wasm module. I looked at adding the policy as a custom section of the wasm module but that is only available from the "outside" of the module not from within which is what we want. Since we want to be able to run this from the command line, and from a server environment, we don't want to have to have the whole repository checked out to be able to generate this "static" component module.

What I've done in this draft is create a webassembly component module named static-evaluator that imports the policy engine, and also imports a component named static-config. The static-config component is what we then need to generate for each standalone .wasm. The way this is done is by generating a project on the file system, including the source for the static config component. This source has the wit is inlined so it does not have to have access to the wit files in this repository. This will then be compiled to a core wasm module, then programatically create a component of that core wasm module. Then we compose a new component using the component we just created and the policy-engine component. This generate component is what can then be run in a wasm runtime that supports the component model.

The drawbacks of the current solution is that it requires the environment this is run on to have a Rust compiler and also support the target wasm32-unknown-unknown. And the policy-engine component and the static-evaluator component must also be available on the file system.

Outstanding tasks

Follow up tasks