Cedar policy engine for Java via WebAssembly.
Evaluates Cedar authorization policies in pure Java by compiling the Cedar Rust crate to Wasm and running it through Endive. No JNI, no native binaries — runs everywhere the JVM runs.
<dependency>
<groupId>io.roastedroot</groupId>
<artifactId>cedar4j</artifactId>
<version>${cedar4j.version}</version>
</dependency>CedarEngine engine = CedarEngine.create();
AuthorizationRequest request = AuthorizationRequest.builder()
.principal("User", "alice")
.action("Action", "view")
.resource("Document", "doc1")
.build();
PolicySet policies = PolicySet.of(
Policy.of("permit(principal, action, resource);", "allow-all"));
AuthorizationResponse response = engine.isAuthorized(
request, policies, Collections.emptySet());
response.isAllowed(); // true
response.decision(); // Decision.ALLOW
response.reasons(); // ["allow-all"]EntityUID alice = EntityUID.of("User", "alice");
EntityUID admins = EntityUID.of("Group", "admins");
Set<Entity> entities = Set.of(
Entity.of(alice, Set.of(admins)),
Entity.of(admins));
Map<String, Object> context = Map.of("authenticated", true);
AuthorizationRequest request = AuthorizationRequest.builder()
.principal(alice)
.action("Action", "delete")
.resource("Document", "doc1")
.context(context)
.build();
PolicySet policies = PolicySet.of(Policy.of(
"permit(principal, action, resource) when { principal in Group::\"admins\" };",
"admin-access"));
AuthorizationResponse response = engine.isAuthorized(request, policies, entities);Schema schema = Schema.fromCedar(
"entity User;\n"
+ "entity Photo;\n"
+ "action viewPhoto appliesTo { principal: [User], resource: [Photo] };");
ValidationRequest request = ValidationRequest.builder()
.schema(schema)
.policies(policies)
.build();
ValidationResponse response = engine.validate(request);
response.isValid(); // true if no validation errors
response.validationErrors(); // list of ValidationErrorPre-parse policies for repeated evaluations:
engine.cachePolicySet("my-policies", policies);
AuthorizationResponse response = engine.isAuthorizedCached(
request, "my-policies", entities);Evaluate with unknown principal, action, or resource:
PartialAuthorizationRequest partial = PartialAuthorizationRequest.builder()
.action("Action", "view")
.resource("Document", "doc1")
.build();
PartialAuthorizationResponse response = engine.isAuthorizedPartial(
partial, policies, entities);
response.decision(); // ALLOW or DENY
response.nontrivialResiduals(); // policies that couldn't be fully evaluatedWasm instances are not thread-safe. Use CedarEnginePool for concurrent access:
CedarEnginePool pool = CedarEnginePool.create(4);
try (CedarEnginePool.Loan loan = pool.borrow()) {
AuthorizationResponse response = loan.engine().isAuthorized(
request, policies, entities);
}CedarEngine engine = CedarEngine.builder()
.withObjectMapper(myCustomMapper)
.build();A low-level string-based API is available for advanced use cases via engine.raw():
String result = engine.raw().authorize(requestJson);
String parsed = engine.raw().parsePolicy(policyText);
String formatted = engine.raw().formatPolicies(policiesText);See CedarRawEngine for the full list of raw methods.
mvn clean verifyTo rebuild the Wasm binary (requires Rust):
cd wasm-build
make allApache-2.0