Andrea Cosentino created CAMEL-24741:
----------------------------------------
Summary: camel-opa - add an in-process WASM evaluation mode
alongside the REST client
Key: CAMEL-24741
URL: https://issues.apache.org/jira/browse/CAMEL-24741
Project: Camel
Issue Type: New Feature
Reporter: Andrea Cosentino
Assignee: Andrea Cosentino
h2. Background
{{camel-opa}} evaluates policies by calling a running OPA server over its REST
Data API ({{com.styra:opa}}). That is the mainstream OPA deployment - a sidecar
next to the application - but it is not the only one, and it costs a blocking
network round-trip per exchange.
OPA can compile Rego to WebAssembly ({{opa build -t wasm -e <entrypoint>}}),
and {{com.styra.opa:opa-java-wasm}} evaluates such a bundle in-process. The
component documentation currently records this as deliberately deferred because
the artifact was at 0.0.6; that is no longer true:
* {{com.styra.opa:opa-java-wasm}} *1.1.0* (2026-06), Apache-2.0, on Maven
Central
* the runtime is {{run.endive:runtime}} - {{bytecodealliance/endive}}, *pure
Java*, no native libraries and no platform classifiers, so there is no
ppc64le/s390x portability problem
* {{opa build -t wasm}} is supported by the
{{openpolicyagent/opa:1.9.0-static}} image the component already uses for its
integration tests
h2. Proposal
Add WASM as a *second* evaluation mode rather than replacing the REST client.
The two are complementary:
|| || REST / sidecar || WASM in-process ||
| policy source | live server, centrally managed | compiled bundle shipped with
the app |
| policy updates | bundle polling, live | redeploy or reload |
| decision logs | yes | none |
| latency | network round-trip | in-process |
| unreachable PDP | a real failure mode | cannot happen |
Removing the REST path would lose decision logging, bundle distribution and
central policy management, which is why this is additive.
h3. Shape
* {{evaluationMode}} (or inferred from a {{policyBundle}} being set): {{rest}}
(default, today's behaviour) or {{wasm}}
* {{policyBundle}} - the compiled {{.wasm}}, resolvable from file, classpath or
URL
* {{entrypoint}} - the compiled entrypoint name; note this is *not* the same
thing as {{policyPath}}, which is a data path. An entrypoint is fixed at {{opa
build -e}} time.
* An {{OpaWasmEvaluator}} satisfying the same internal contract as
{{OpaPolicyEvaluator}}, so the producer, {{OpaSecurityPolicy}} and the decision
headers are unchanged.
h3. Thread safety is not optional here
{{OpaPolicy}} is *not* thread-safe: it carries mutable input/data and a
package-private {{reset()}}, and the library ships {{OpaPolicyPool}} with
{{borrow()}} / {{Loan}} for exactly this reason. A Camel producer is invoked
concurrently, so a single shared {{OpaPolicy}} instance would be a correctness
bug under load rather than a performance question. The pool must be used, and
its size becomes an option ({{poolSize}}, defaulting to something derived from
the context or a small constant).
h3. Result shape differs
{{OpaPolicy.evaluate()}} returns a JSON *string*, and the WASM ABI wraps
results in an array. The existing {{allowKey}} / {{isAllowed}} handling has to
unwrap that consistently so a policy behaves identically in both modes - a
route must not have to know which engine evaluated it.
h3. Options that stop applying
{{serverUrl}}, {{bearerToken}} and {{failOpen}} are meaningless in WASM mode,
as are the health checks from CAMEL-24644 and CAMEL-24736 - there is no server
to probe. They must be rejected or ignored explicitly with a clear message
rather than silently doing nothing, since silently ignoring {{failOpen}} would
be a security surprise.
h2. Scope
{{main}} only. Additive; {{rest}} stays the default so existing routes are
unaffected.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)