Open Policy Agent WebAssembly SDK
npm install @open-policy-agent/opa-wasmWork 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.
`javascript`
const { loadPolicy } = require("@open-policy-agent/opa-wasm");
`javascript`
loadPolicy(policyWasm);
The loadPolicy function returns a Promise with the loaded policy. Typicallyasync
this means loading it in an function like:
`javascript`
const policy = await loadPolicy(policyWasm);
Or something like:
`javascript`
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:
`javascript
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 or ArrayBuffer, which assumed to be a
well-formed stringified JSON
evaluate(input) -- Evaluates the policy using any loaded data and the suppliedinput document.
- input parameter MAY be an object, primitive literal or ArrayBuffer,
which assumed to be a well-formed stringified JSON
> ArrayBuffer supported in the APIs above as a performance optimisationArrayBuffer
> feature, given that either network or file system provided contents can easily
> be represented as in a very performant way.
Example:
`javascript
input = '{"path": "/", "role": "admin"}';
loadPolicy(policyWasm).then((policy) => {
resultSet = policy.evaluate(input);
if (resultSet == null) {
console.error("evaluation error");
} else if (resultSet.length == 0) {
console.log("undefined");
} else {
console.log("allowed = " + resultSet[0].result);
}
}).catch((error) => {
console.error("Failed to load policy: ", error);
});
`
> For any opa build created WASM binaries the result set, when defined, willresult
> contain a 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+:
`bash`
opa build -t wasm -e example/allow example.rego
Which is compiling the example.rego policy file with the result set todata.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
denonpm
installed locally,
the same checks can be invoked using :
- npm run lintnpm 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.
The published package provides four different entrypoints for consumption:
1. A CommonJS module for consumption with older versions of Node or those using
require():`
js`
const { loadPolicy } = require("@open-policy-agent/opa-wasm");
`
1. An ESM module for consumption with newer versions of Node:
js`
import { loadPolicy } from "@open-policy-agent/opa-wasm";
`
1. An ESM module for consumption in modern browsers (this will contain all
dependencies already bundled and can be used standalone).
html`
opa
1. A script for consumption in all browsers (this will export an global`
variable).
js`
The browser builds are generated in the ./build.sh script and useesbuild
[][esbuild]. All exports are defined in the exports field in the
package.json file. More detials on how these work are described in the
[Conditional Exports][conditional-exports] documentation.
For TypeScript projects we also generate an opa.d.ts declaration file that will
give correct typings and is also defined under the types` field in the
package.json.
[esbuild]: https://esbuild.github.io/
[conditional-exports]: https://nodejs.org/api/packages.html#conditional-exports