Work in Progress -- Contributions welcome!!
This is the source for the @open-policy-agent/opa-wasm NPM module which is a small SDK for using WebAssembly (wasm) compiled Open Policy Agent Rego policies.
npm install @open-policy-agent/opa-wasm
There are only a couple of steps required to start evaluating the policy.
const { loadPolicy } = require("@open-policy-agent/opa-wasm");
loadPolicy(policyWasm);
The loadPolicy
function returns a Promise with the loaded policy. Typically
this means loading it in an async
function like:
const policy = await loadPolicy(policyWasm);
Or something like:
loadPolicy(policyWasm).then((policy) => {
// evaluate or save the policy
}, (error) => {
console.error("Failed to load policy: " + error);
});
The policyWasm
needs to be either the raw byte array of the compiled policy
Wasm file, or a WebAssembly module.
For example:
const fs = require("fs");
const policyWasm = fs.readFileSync("policy.wasm");
Alternatively the bytes can be pulled in remotely from a fetch
or in some
cases (like CloudFlare Workers) the Wasm binary can be loaded directly into the
javascript context through external APIs.
The loaded policy object returned from loadPolicy()
has a couple of important
APIs for policy evaluation:
setData(data)
-- Provide an external data
document for policy evaluation.
data
MUST be a serializable object orArrayBuffer
, which assumed to be a well-formed stringified JSON
evaluate(input)
-- Evaluates the policy using any loaded data and the supplied
input
document.
input
parameter MAY be anobject
, primitive literal orArrayBuffer
, which assumed to be a well-formed stringified JSON
ArrayBuffer
supported in the APIs above as a performance optimisation feature, given that either network or file system provided contents can easily be represented asArrayBuffer
in a very performant way.
Example:
input = '{"path": "/", "role": "admin"}';
loadPolicy(policyWasm).then((policy) => {
resultSet = policy.evaluate(input);
if (resultSet == null) {
console.error("evaluation error");
}
if (resultSet.length == 0) {
console.log("undefined");
}
console.log("allowed = " + allowed[0].result);
}).catch((error) => {
console.error("Failed to load policy: ", error);
});
For any
opa build
created WASM binaries the result set, when defined, will contain aresult
key with the value of the compiled entrypoint. See https://www.openpolicyagent.org/docs/latest/wasm/ for more details.
See https://www.openpolicyagent.org/docs/latest/how-do-i-write-policies/
Either use the
Compile REST API
or opa build
CLI tool.
For example, with OPA v0.20.5+:
opa build -t wasm -e 'example/allow' example.rego
Which is compiling the example.rego
policy file with the result set to
data.example.allow
. The result will be an OPA bundle with the policy.wasm
binary included. See ./examples for a more comprehensive example.
See opa build --help
for more details.
This project is using Deno's
lint and
formatter tools in CI. With
deno
installed locally,
the same checks can be invoked using npm
:
npm run lint
npm run fmt
-- this will fix the formattingnpm run fmt:check
-- this happens in CI
All of these operate on git-tracked files, so make sure you've committed the
code you'd like to see checked. Alternatively, you can invoke
deno lint my_new_file.js
directly, too.