This is an SDK for using WebAssembly(wasm) compiled Open Policy Agent policies with Java powered by Endive, a pure Java Wasm runtime.
Initial implementation was based on Open Policy Agent WebAssembly NPM Module and Open Policy Agent WebAssembly dotnet core SDK
We want fast, in-process and secure OPA policies evaluation, and avoid network bottlenecks when using opa-java.
Using this integration for policy evaluation you can switch from the traditional integration pattern:
to a fully embedded:
With Maven add the core module dependency:
<dependency>
<groupId>org.openpolicyagent</groupId>
<artifactId>opa-java-wasm</artifactId>
<version>latest_release</version>
</dependency>There are only a couple of steps required to start evaluating the policy.
import org.openpolicyagent.wasm.OpaPolicy;var policy = OpaPolicy.builder().withPolicy(policyWasm).build();The policyWasm can be a variety of things, including raw byte array, InputStream, Path, File.
The content should be the compiled policy Wasm file, a valid WebAssembly module.
For example:
var policy = OpaPolicy.builder().withPolicy(new File("policy.wasm")).build();The OpaPolicy object returned from loadPolicy() has a couple of important
APIs for policy evaluation:
data(data) -- Provide an external data document for policy evaluation.
dataMUST be aString, which assumed to be a well-formed stringified JSON
evaluate(input) -- Evaluates the policy using any loaded data and the supplied
input document.
inputparameter MUST be aStringserializedobject,arrayor primitive literal which assumed to be a well-formed stringified JSON
Example:
var input = "{\"path\": \"/\", \"role\": \"admin\"}";
var policy = OpaPolicy.builder().withPolicy(policyWasm).build();
var result = policy.evaluate(input);
System.out.println("Result is: " + result);For any
opa buildcreated WASM binaries the result set, when defined, will contain aresultkey with the value of the compiled entrypoint. See https://www.openpolicyagent.org/docs/latest/wasm/ for more details.
OpaPolicyPool manages a bounded set of OpaPolicy instances for concurrent
use. It uses lock-free data structures internally, so it is safe to use with
virtual threads (no carrier-thread pinning).
import org.openpolicyagent.wasm.OpaPolicyPool;
var pool = OpaPolicyPool.create(
() -> OpaPolicy.builder().withPolicy(policyWasm).build(),
4); // at most 4 concurrent instances
try (var loan = pool.borrow()) { // blocks if all 4 are in use
loan.policy()
.data("{\"role\": {\"alice\": \"admin\"}}")
.input("{\"user\": \"alice\"}");
String result = loan.policy().evaluate();
}
// policy is automatically returned to the pool
pool.close();Each policy is reset to a clean state when returned to the pool (data, input and entrypoint are cleared), so the next borrower always starts fresh.
If a processing error may have left the policy in a bad state, call
loan.discard() instead of letting close() return it:
try (var loan = pool.borrow()) {
try {
loan.policy().data(data).input(input);
result = loan.policy().evaluate();
} catch (RuntimeException ex) {
loan.discard(); // destroys this instance; pool will create a fresh one
// handle error ...
}
}Note: A single
OpaPolicyinstance is not thread-safe. Without the pool, use one instance per thread.
At the moment the following builtins are supported(and, by default, automatically injected when needed):
-
String
sprintfNOTE: this implementation is SDK-dependent and might generate different results depending on the runtime, please, limit the usage to trivial use-cases.
-
Json
json.is_valid
-
Yaml
yaml.is_validyaml.marshalyaml.unmarshal
See https://www.openpolicyagent.org/docs/policy-language
Either use the
Compile REST API
or opa build CLI tool.
For example:
opa build -t wasm -e example/allow example.regoWhich 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 SDK is community supported and maintained. For bug reports and feature requests, please use Github issues. For real-time support, please join the Open Policy Agent Slack.
To develop this library you need to have installed the following tools:
- Java 11+
- Maven
- the
opacli tar
the typical command to build and run the tests is:
mvn spotless:apply clean installto disable the tests based on the Opa testsuite:
OPA_TESTSUITE=disabled mvn spotless:apply installThe versions in core/pom.xml are updated as part of the release process.
New releases are manually triggered by running the
release workflow.
This workflow requires a number of secrets to be set, while OSSRH_PASSWORD and
username should not need to be rotated, JAVA_GPG_SECRET_KEY should be updated
if the key has expired and has been removed from the
keyserver. This secret is not base64
encoded.
An example error from a release run where they key has expired, note that this
is not the final error about Remote staging failed: Staging rules failure!.
No public key: Key with id: (78fe9b032725616c) was not able to be located on <a href=http://keyserver.ubuntu.com:11371/>http://keyserver.ubuntu.com:11371/</a>. Upload your public key and try the operation again.