Skip to content

Commit d049db5

Browse files
andreaTPclaude
andcommitted
Add Wasm-based Cedar policy engine (pure Java, no JNI required)
Compiles the Cedar Rust crate to WebAssembly and runs it via Chicory Redline — eliminating native library cross-compilation while keeping competitive performance with the JNI implementation. Signed-off-by: andreatp <andrea.peruffo1982@gmail.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent da85f1a commit d049db5

21 files changed

Lines changed: 2307 additions & 0 deletions

File tree

CedarWasm/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
wasm-build/target/
2+
core/target/
3+
benchmark/target/

CedarWasm/README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Cedar Wasm
2+
3+
Pure-Java Cedar policy engine using WebAssembly. The Cedar Rust crate is compiled to Wasm and executed via [Chicory Redline](https://github.com/AnyTimeTraveler/chicory-redline) — no JNI or native libraries required.
4+
5+
## Project structure
6+
7+
```
8+
CedarWasm/
9+
├── wasm-build/ Rust crate compiled to wasm32-unknown-unknown
10+
├── core/ Java module (CedarEngine + Chicory Redline)
11+
└── benchmark/ JMH benchmarks comparing JNI vs Wasm
12+
```
13+
14+
## Prerequisites
15+
16+
- Java 17+
17+
- Rust 1.89+ with `wasm32-unknown-unknown` target
18+
- `wasm-opt` (from [binaryen](https://github.com/WebAssembly/binaryen))
19+
- [Chicory Redline](https://github.com/AnyTimeTraveler/chicory-redline) installed to local Maven repo (`mvn install -DskipTests`)
20+
21+
## Building the Wasm module
22+
23+
```bash
24+
cd wasm-build
25+
rustup target add wasm32-unknown-unknown
26+
cargo build --release --target wasm32-unknown-unknown
27+
wasm-opt --enable-bulk-memory -O3 \
28+
target/wasm32-unknown-unknown/release/cedar_wasm.wasm \
29+
-o ../core/wasm/cedar_wasm.wasm
30+
```
31+
32+
## Building and testing
33+
34+
```bash
35+
cd CedarWasm
36+
mvn clean test -pl core
37+
```
38+
39+
## Running benchmarks (JNI vs Wasm)
40+
41+
First, build the JNI uber jar (requires Gradle + Rust):
42+
43+
```bash
44+
cd CedarJava
45+
./gradlew uberJar -x test -x spotbugsMain -x spotbugsTest -x spotbugsJmh \
46+
-x checkstyleMain -x checkstyleTest -x jacocoTestCoverageVerification
47+
```
48+
49+
Then run the benchmarks:
50+
51+
```bash
52+
cd CedarWasm
53+
mvn install -DskipTests
54+
mvn exec:java -pl benchmark
55+
```
56+
57+
## Sample results
58+
59+
```
60+
Benchmark Mode Cnt Score Error Units
61+
CedarBenchmark.jniCachedLarge avgt 3 1077.137 ± 2500.105 us/op
62+
CedarBenchmark.jniCachedMedium avgt 3 68.613 ± 44.063 us/op
63+
CedarBenchmark.jniCachedSmall avgt 3 29.142 ± 7.306 us/op
64+
CedarBenchmark.jniCachedXLarge avgt 3 476.329 ± 1036.358 us/op
65+
CedarBenchmark.jniUncachedLarge avgt 3 2209.292 ± 2208.573 us/op
66+
CedarBenchmark.jniUncachedMedium avgt 3 335.507 ± 269.147 us/op
67+
CedarBenchmark.jniUncachedSmall avgt 3 64.400 ± 20.911 us/op
68+
CedarBenchmark.jniUncachedXLarge avgt 3 9672.329 ± 1197.832 us/op
69+
CedarBenchmark.wasmCachedLarge avgt 3 2080.047 ± 1085.834 us/op
70+
CedarBenchmark.wasmCachedMedium avgt 3 218.603 ± 112.547 us/op
71+
CedarBenchmark.wasmCachedSmall avgt 3 131.787 ± 148.610 us/op
72+
CedarBenchmark.wasmCachedXLarge avgt 3 906.421 ± 664.702 us/op
73+
CedarBenchmark.wasmUncachedLarge avgt 3 2788.757 ± 364.868 us/op
74+
CedarBenchmark.wasmUncachedMedium avgt 3 840.366 ± 441.384 us/op
75+
CedarBenchmark.wasmUncachedSmall avgt 3 233.398 ± 41.424 us/op
76+
CedarBenchmark.wasmUncachedXLarge avgt 3 21890.498 ± 12325.095 us/op
77+
```

CedarWasm/benchmark/pom.xml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<parent>
5+
<groupId>com.cedarpolicy</groupId>
6+
<artifactId>cedar-wasm-parent</artifactId>
7+
<version>4.0.0-SNAPSHOT</version>
8+
</parent>
9+
<artifactId>cedar-benchmark</artifactId>
10+
<name>Cedar JNI vs Wasm Benchmark</name>
11+
12+
<dependencies>
13+
<!-- Wasm implementation -->
14+
<dependency>
15+
<groupId>com.cedarpolicy</groupId>
16+
<artifactId>cedar-wasm</artifactId>
17+
<version>${project.version}</version>
18+
</dependency>
19+
<!-- JNI implementation (uber jar from Gradle build) -->
20+
<dependency>
21+
<groupId>com.cedarpolicy</groupId>
22+
<artifactId>cedar-java</artifactId>
23+
<version>3.1.2</version>
24+
<scope>system</scope>
25+
<systemPath>${project.basedir}/../../CedarJava/build/libs/CedarJava-uber.jar</systemPath>
26+
</dependency>
27+
<!-- JNI runtime dependencies -->
28+
<dependency>
29+
<groupId>com.fasterxml.jackson.core</groupId>
30+
<artifactId>jackson-databind</artifactId>
31+
<version>2.20.0</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>com.fasterxml.jackson.datatype</groupId>
35+
<artifactId>jackson-datatype-jdk8</artifactId>
36+
<version>2.20.0</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>com.fizzed</groupId>
40+
<artifactId>jne</artifactId>
41+
<version>4.5.3</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>com.google.guava</groupId>
45+
<artifactId>guava</artifactId>
46+
<version>33.5.0-jre</version>
47+
</dependency>
48+
<!-- JMH -->
49+
<dependency>
50+
<groupId>org.openjdk.jmh</groupId>
51+
<artifactId>jmh-core</artifactId>
52+
<version>${jmh.version}</version>
53+
</dependency>
54+
<dependency>
55+
<groupId>org.openjdk.jmh</groupId>
56+
<artifactId>jmh-generator-annprocess</artifactId>
57+
<version>${jmh.version}</version>
58+
</dependency>
59+
</dependencies>
60+
61+
<build>
62+
<plugins>
63+
<plugin>
64+
<groupId>org.apache.maven.plugins</groupId>
65+
<artifactId>maven-compiler-plugin</artifactId>
66+
<configuration>
67+
<annotationProcessorPaths>
68+
<path>
69+
<groupId>org.openjdk.jmh</groupId>
70+
<artifactId>jmh-generator-annprocess</artifactId>
71+
<version>${jmh.version}</version>
72+
</path>
73+
</annotationProcessorPaths>
74+
</configuration>
75+
</plugin>
76+
<plugin>
77+
<groupId>org.codehaus.mojo</groupId>
78+
<artifactId>exec-maven-plugin</artifactId>
79+
<version>3.5.0</version>
80+
<configuration>
81+
<classpathScope>test</classpathScope>
82+
<mainClass>org.openjdk.jmh.Main</mainClass>
83+
<arguments>
84+
<argument>-f</argument>
85+
<argument>0</argument>
86+
<argument>-i</argument>
87+
<argument>3</argument>
88+
<argument>-wi</argument>
89+
<argument>3</argument>
90+
<argument>-r</argument>
91+
<argument>1</argument>
92+
<argument>-w</argument>
93+
<argument>1</argument>
94+
</arguments>
95+
</configuration>
96+
</plugin>
97+
</plugins>
98+
</build>
99+
</project>

0 commit comments

Comments
 (0)