This is an automated email from the ASF dual-hosted git repository.

oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new ea12ca33bfe7 CAMEL-24740: camel-opa - support batch policy evaluation 
(#26679)
ea12ca33bfe7 is described below

commit ea12ca33bfe7383860105ddc453f785dc779ae1c
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Sep 25 11:06:45 2026 +0200

    CAMEL-24740: camel-opa - support batch policy evaluation (#26679)
    
    * CAMEL-24740: camel-opa - support batch policy evaluation
    
    A route that splits a payload and authorizes each element paid one OPA 
round-trip
    per element. The producer now takes a batch option: with batch=true and a 
List
    body it builds one input document per element - each element as the body, 
sharing
    the exchange's headers and properties - and evaluates them in a single call
    through OPA's batch API (OPAClient.evaluateBatch, which the SDK falls back 
to
    sequential requests for when the server does not implement the endpoint).
    
    The per-element verdicts are reported in CamelOpaBatchDecision, a 
List<Boolean>
    parallel to the input; CamelOpaDecisionAllow is not set in batch mode. The 
header
    is cleared on entry and withheld from the OPA input like the other decision
    headers.
    
    Fail-closed is per element: an element whose evaluation could not be 
reached is
    denied, or allowed under failOpen, while the others decide normally - the 
batch
    is never denied as a whole because one element failed, nor allowed because 
most
    succeeded. Only a call that fails entirely denies (or, under failOpen, 
allows)
    every element. That is the part the issue calls out as not mechanical.
    
    Batch is rest-only and rejected with evaluationMode=wasm at startup: it 
saves the
    per-element HTTP round-trip, which has no meaning for in-process 
evaluation. The
    wasm evaluator inherits the base evaluator's refusal.
    
    OpaBatchEvaluationTest (mocked OPAClient) covers the parallel verdicts, a 
failed
    element denied while its neighbours decide, the same element allowed under
    failOpen, the List-body requirement, and the wasm rejection.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
    
    * CAMEL-24740: camel-opa - short-circuit an empty batch, set the 
policy-path header, and cover whole-batch failure
    
    Addresses review feedback on batch evaluation:
    - an empty List body is answered without calling the OPA SDK, whose
      behaviour on an empty batch is undefined, so the verdict list is a
      deterministic empty list rather than a possible fail-closed error.
    - CamelOpaPolicyPath is now set in batch mode too, so observability
      tooling reads the same header it does after a single evaluation.
    - added tests for the whole-batch failure path, both fail-closed and
      under failOpen, and for the empty-batch short-circuit.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
    
    * CAMEL-24740: correct what the batch docs claim about headers and total 
failure
    
    Addresses review feedback on #26679.
    
    Two statements did not match the code.
    
    The header paragraph named only CamelOpaDecisionAllow as unset in batch
    mode, so a reader took it that everything else survives.
    setDecisionHeaders writes three headers and setBatchDecisionHeaders
    writes two, so CamelOpaDecision is unset as well. Both are now named,
    and CamelOpaPolicyPath is stated positively as set, since tooling may
    want to rely on it.
    
    "Only a call that fails entirely ... denies every element" described the
    fail-closed whole-batch case as a denial, but that path throws and
    leaves no verdict, as failsClosedWhenTheWholeBatchCannotBeEvaluated
    asserts. Someone reading it would write code expecting a List of false.
    It now says the exchange fails and carries no verdict. The failOpen half
    was accurate and keeps its meaning.
    
    Documentation only. The catalog mirror is updated with it.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
    
    * CAMEL-24740: regenerate the opa catalog for both new headers
    
    Rebasing onto main brought CAMEL-24738's CamelOpaDecisionFailedOpen
    alongside this branch's CamelOpaBatchDecision, and the generated
    metadata conflicted because each side had regenerated it with only its
    own header.
    
    Taking either side would have dropped a header from the catalog: the
    conflicted file listed four, and the component ships five. Regenerated
    from the merged OpaConstants instead, and the catalog copy taken from
    that output rather than hand-merged.
    
    The two conflicts in OpaPolicyEvaluator were resolved the same way, and
    they are the ones that mattered: clearDecisionHeaders now removes both
    new headers and isDecisionHeader lists both. Keeping only one would have
    left the other attacker-settable on entry and sent it to OPA as input,
    which is the bug CAMEL-24754 and CAMEL-24738 exist to prevent.
    
    99 tests green.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
    
    * Regen
    
    ---------
    
    Signed-off-by: Andrea Cosentino <[email protected]>
    Co-authored-by: Claude Opus 4.8 <[email protected]>
    Co-authored-by: Guillaume Nodet <[email protected]>
---
 .../org/apache/camel/catalog/components/opa.json   |  79 ++++-----
 .../apache/camel/catalog/docs/opa-component.adoc   |  31 ++++
 .../component/opa/OpaComponentConfigurer.java      |   3 +
 .../camel/component/opa/OpaEndpointConfigurer.java |   3 +
 .../camel/component/opa/OpaEndpointUriFactory.java |   3 +-
 .../org/apache/camel/component/opa/opa.json        |  79 ++++-----
 .../camel-opa/src/main/docs/opa-component.adoc     |  31 ++++
 .../camel/component/opa/OpaConfiguration.java      |  20 +++
 .../apache/camel/component/opa/OpaConstants.java   |   7 +
 .../apache/camel/component/opa/OpaEndpoint.java    |   6 +
 .../camel/component/opa/OpaPolicyEvaluator.java    | 128 ++++++++++++++-
 .../apache/camel/component/opa/OpaProducer.java    |  15 +-
 .../camel/component/opa/OpaRestEvaluator.java      |  26 +++
 .../component/opa/OpaBatchEvaluationTest.java      | 176 +++++++++++++++++++++
 .../component/dsl/OpaComponentBuilderFactory.java  |  27 ++++
 .../endpoint/dsl/OpaEndpointBuilderFactory.java    |  63 ++++++++
 16 files changed, 616 insertions(+), 81 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
index 099541bf5a47..a98f123dc071 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
@@ -25,52 +25,55 @@
   },
   "componentProperties": {
     "allowKey": { "index": 0, "kind": "property", "displayName": "Allow Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "allow", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The key to read the allow\/deny verdict from 
when the policy returns an object rather than a plain b [...]
-    "configuration": { "index": 1, "kind": "property", "displayName": 
"Configuration", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.camel.component.opa.OpaConfiguration", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
component configuration." },
-    "entrypoint": { "index": 2, "kind": "property", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed wh 
[...]
-    "evaluationMode": { "index": 3, "kind": "property", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a running [...]
-    "includeBody": { "index": 4, "kind": "property", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can b [...]
-    "includeHeaders": { "index": 5, "kind": "property", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defau [...]
-    "includeProperties": { "index": 6, "kind": "property", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all of [...]
-    "lazyStartProducer": { "index": 7, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "policyBundle": { "index": 8, "kind": "property", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {co [...]
-    "serverUrl": { "index": 9, "kind": "property", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defaul [...]
-    "autowiredEnabled": { "index": 10, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
-    "borrowTimeout": { "index": 11, "kind": "property", "displayName": "Borrow 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the e [...]
-    "connectionTimeout": { "index": 12, "kind": "property", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest mo [...]
-    "opaClient": { "index": 13, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 14, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
-    "requestTimeout": { "index": 15, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
-    "healthCheckConsumerEnabled": { "index": 16, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
-    "healthCheckProducerEnabled": { "index": 17, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
-    "bearerToken": { "index": 18, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
-    "failOpen": { "index": 19, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy cannot be evalua [...]
-    "sslContextParameters": { "index": 20, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
-    "useGlobalSslContextParameters": { "index": 21, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
+    "batch": { "index": 1, "kind": "property", "displayName": "Batch", 
"group": "producer", "label": "producer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Authorize a whole collection in one call. When 
enabled the producer expects a List body, evaluates one input  [...]
+    "configuration": { "index": 2, "kind": "property", "displayName": 
"Configuration", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.camel.component.opa.OpaConfiguration", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
component configuration." },
+    "entrypoint": { "index": 3, "kind": "property", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed wh 
[...]
+    "evaluationMode": { "index": 4, "kind": "property", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a running [...]
+    "includeBody": { "index": 5, "kind": "property", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can b [...]
+    "includeHeaders": { "index": 6, "kind": "property", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defau [...]
+    "includeProperties": { "index": 7, "kind": "property", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all of [...]
+    "lazyStartProducer": { "index": 8, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
+    "policyBundle": { "index": 9, "kind": "property", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {co [...]
+    "serverUrl": { "index": 10, "kind": "property", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defau [...]
+    "autowiredEnabled": { "index": 11, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
+    "borrowTimeout": { "index": 12, "kind": "property", "displayName": "Borrow 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the e [...]
+    "connectionTimeout": { "index": 13, "kind": "property", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest mo [...]
+    "opaClient": { "index": 14, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 15, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
+    "requestTimeout": { "index": 16, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
+    "healthCheckConsumerEnabled": { "index": 17, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
+    "healthCheckProducerEnabled": { "index": 18, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
+    "bearerToken": { "index": 19, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
+    "failOpen": { "index": 20, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy cannot be evalua [...]
+    "sslContextParameters": { "index": 21, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
+    "useGlobalSslContextParameters": { "index": 22, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
   },
   "headers": {
     "CamelOpaDecisionAllow": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The allow\/deny verdict of the policy 
evaluation. Always overwritten by the component, so a value set by an inbound 
message never survives into the route.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#DECISION_ALLOW" },
     "CamelOpaDecision": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Object", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The raw decision document returned by OPA. 
Useful for policies that return more than a boolean, such as obligations, row 
filters or deny reasons.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#DECISION" },
     "CamelOpaPolicyPath": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The policy path that was evaluated. Set by the 
component for observability; it is not read as an input and cannot be used to 
select a different policy.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#POLICY_PATH" },
-    "CamelOpaDecisionFailedOpen": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true only when the exchange 
proceeded because failOpen is enabled and the policy could not be evaluated - 
nothing authorized it. Absent on every decision an actual policy made, so a 
route or an audit trail can tell the  [...]
+    "CamelOpaDecisionFailedOpen": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true only when the exchange 
proceeded because failOpen is enabled and the policy could not be evaluated - 
nothing authorized it. Absent on every decision an actual policy made, so a 
route or an audit trail can tell the  [...]
+    "CamelOpaBatchDecision": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.List<Boolean>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The per-element 
allow\/deny verdicts of a batch evaluation (batch=true), as a List of Boolean 
parallel to the List body. Always overwritten by the component. An element 
whose evaluation could not be reached is denie [...]
   },
   "properties": {
     "policyPath": { "index": 0, "kind": "path", "displayName": "Policy Path", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Path of the Rego rule head 
to evaluate, relative to the OPA data document. For a rule named allow in a 
policy declaring package authz.orders, this is authz\/orders\/allow. The path 
is taken from the endpoint only: i [...]
     "allowKey": { "index": 1, "kind": "parameter", "displayName": "Allow Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "allow", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The key to read the allow\/deny verdict from 
when the policy returns an object rather than a plain  [...]
-    "entrypoint": { "index": 2, "kind": "parameter", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed w 
[...]
-    "evaluationMode": { "index": 3, "kind": "parameter", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a runnin [...]
-    "includeBody": { "index": 4, "kind": "parameter", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can  [...]
-    "includeHeaders": { "index": 5, "kind": "parameter", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defa [...]
-    "includeProperties": { "index": 6, "kind": "parameter", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all o [...]
-    "policyBundle": { "index": 7, "kind": "parameter", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {c [...]
-    "serverUrl": { "index": 8, "kind": "parameter", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defau [...]
-    "lazyStartProducer": { "index": 9, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
-    "borrowTimeout": { "index": 10, "kind": "parameter", "displayName": 
"Borrow Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the  [...]
-    "connectionTimeout": { "index": 11, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest m [...]
-    "opaClient": { "index": 12, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 13, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
-    "requestTimeout": { "index": 14, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
-    "bearerToken": { "index": 15, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
-    "failOpen": { "index": 16, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy cannot be evalu [...]
-    "sslContextParameters": { "index": 17, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
+    "batch": { "index": 2, "kind": "parameter", "displayName": "Batch", 
"group": "producer", "label": "producer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Authorize a whole collection in one call. When 
enabled the producer expects a List body, evaluates one input [...]
+    "entrypoint": { "index": 3, "kind": "parameter", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed w 
[...]
+    "evaluationMode": { "index": 4, "kind": "parameter", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a runnin [...]
+    "includeBody": { "index": 5, "kind": "parameter", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can  [...]
+    "includeHeaders": { "index": 6, "kind": "parameter", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defa [...]
+    "includeProperties": { "index": 7, "kind": "parameter", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all o [...]
+    "policyBundle": { "index": 8, "kind": "parameter", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {c [...]
+    "serverUrl": { "index": 9, "kind": "parameter", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defau [...]
+    "lazyStartProducer": { "index": 10, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
+    "borrowTimeout": { "index": 11, "kind": "parameter", "displayName": 
"Borrow Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the  [...]
+    "connectionTimeout": { "index": 12, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest m [...]
+    "opaClient": { "index": 13, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 14, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
+    "requestTimeout": { "index": 15, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
+    "bearerToken": { "index": 16, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
+    "failOpen": { "index": 17, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy cannot be evalu [...]
+    "sslContextParameters": { "index": 18, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
index d674ffa40aed..9af5c30402db 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/opa-component.adoc
@@ -180,6 +180,37 @@ boolean verdict read out of it:
 Both headers are written on every evaluation, so a verdict set by an inbound 
message never survives into the
 route.
 
+== Batch evaluation
+
+A route that splits a payload and authorizes each element pays one OPA 
round-trip per element. Set `batch=true` and
+hand the producer a `List` instead: it builds one input document per element - 
each element as the `body`, sharing
+the exchange's headers and properties - and evaluates them in a single call 
through OPA's batch API (the SDK falls
+back to sequential requests when the server does not implement it).
+
+[source,java]
+------------------------------------------------------------
+from("direct:orders")
+    // the body is a List of orders to authorize
+    .to("opa:authz/orders/allow?batch=true")
+    // CamelOpaBatchDecision is now a List<Boolean> parallel to the body
+    .process(dropTheDeniedOrders);
+------------------------------------------------------------
+
+The per-element verdicts arrive in `CamelOpaBatchDecision`, a `List<Boolean>` 
parallel to the input list: element
+_i_ is allowed when entry _i_ is `true`. Neither `CamelOpaDecisionAllow` nor 
`CamelOpaDecision` is set in batch
+mode - there is no single verdict, and no single decision document - and both 
are cleared on entry like the other
+decision headers, so a value an inbound message supplied never survives. 
`CamelOpaPolicyPath` *is* set, to the same
+value a single evaluation records, so tooling can read it either way.
+
+Fail-closed applies *per element*: an element whose evaluation could not be 
reached is denied (`false`), or allowed
+when `failOpen` is set, while every other element decides normally. The batch 
is never denied as a whole because
+one element failed, nor allowed because most of it succeeded. A call that 
fails entirely - the server could not be
+reached at all - fails the exchange rather than denying each element: it 
carries no verdict at all, not a list of
+`false`. Under `failOpen` that same failure allows every element instead.
+
+`batch` requires `evaluationMode=rest`: it saves the per-element HTTP 
round-trip, which has no meaning for in-process
+`wasm` evaluation, and the endpoint rejects the combination at startup.
+
 [#authorizing-an-identity]
 == Authorizing an identity
 
diff --git 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
index abaee2681400..c548f3b42415 100644
--- 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
+++ 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaComponentConfigurer.java
@@ -34,6 +34,7 @@ public class OpaComponentConfigurer extends 
PropertyConfigurerSupport implements
         case "allowKey": 
getOrCreateConfiguration(target).setAllowKey(property(camelContext, 
java.lang.String.class, value)); return true;
         case "autowiredenabled":
         case "autowiredEnabled": 
target.setAutowiredEnabled(property(camelContext, boolean.class, value)); 
return true;
+        case "batch": 
getOrCreateConfiguration(target).setBatch(property(camelContext, boolean.class, 
value)); return true;
         case "bearertoken":
         case "bearerToken": 
getOrCreateConfiguration(target).setBearerToken(property(camelContext, 
java.lang.String.class, value)); return true;
         case "borrowtimeout":
@@ -88,6 +89,7 @@ public class OpaComponentConfigurer extends 
PropertyConfigurerSupport implements
         case "allowKey": return java.lang.String.class;
         case "autowiredenabled":
         case "autowiredEnabled": return boolean.class;
+        case "batch": return boolean.class;
         case "bearertoken":
         case "bearerToken": return java.lang.String.class;
         case "borrowtimeout":
@@ -138,6 +140,7 @@ public class OpaComponentConfigurer extends 
PropertyConfigurerSupport implements
         case "allowKey": return getOrCreateConfiguration(target).getAllowKey();
         case "autowiredenabled":
         case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "batch": return getOrCreateConfiguration(target).isBatch();
         case "bearertoken":
         case "bearerToken": return 
getOrCreateConfiguration(target).getBearerToken();
         case "borrowtimeout":
diff --git 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
index 469fa36c4faa..14aa10b613ce 100644
--- 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
+++ 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointConfigurer.java
@@ -25,6 +25,7 @@ public class OpaEndpointConfigurer extends 
PropertyConfigurerSupport implements
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowkey":
         case "allowKey": 
target.getConfiguration().setAllowKey(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "batch": 
target.getConfiguration().setBatch(property(camelContext, boolean.class, 
value)); return true;
         case "bearertoken":
         case "bearerToken": 
target.getConfiguration().setBearerToken(property(camelContext, 
java.lang.String.class, value)); return true;
         case "borrowtimeout":
@@ -70,6 +71,7 @@ public class OpaEndpointConfigurer extends 
PropertyConfigurerSupport implements
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowkey":
         case "allowKey": return java.lang.String.class;
+        case "batch": return boolean.class;
         case "bearertoken":
         case "bearerToken": return java.lang.String.class;
         case "borrowtimeout":
@@ -111,6 +113,7 @@ public class OpaEndpointConfigurer extends 
PropertyConfigurerSupport implements
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "allowkey":
         case "allowKey": return target.getConfiguration().getAllowKey();
+        case "batch": return target.getConfiguration().isBatch();
         case "bearertoken":
         case "bearerToken": return target.getConfiguration().getBearerToken();
         case "borrowtimeout":
diff --git 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
index b18d621d92b8..f1e9bc602ef0 100644
--- 
a/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
+++ 
b/components/camel-opa/src/generated/java/org/apache/camel/component/opa/OpaEndpointUriFactory.java
@@ -24,8 +24,9 @@ public class OpaEndpointUriFactory extends 
org.apache.camel.support.component.En
     private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(18);
+        Set<String> props = new HashSet<>(19);
         props.add("allowKey");
+        props.add("batch");
         props.add("bearerToken");
         props.add("borrowTimeout");
         props.add("connectionTimeout");
diff --git 
a/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
 
b/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
index 099541bf5a47..a98f123dc071 100644
--- 
a/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
+++ 
b/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
@@ -25,52 +25,55 @@
   },
   "componentProperties": {
     "allowKey": { "index": 0, "kind": "property", "displayName": "Allow Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "allow", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The key to read the allow\/deny verdict from 
when the policy returns an object rather than a plain b [...]
-    "configuration": { "index": 1, "kind": "property", "displayName": 
"Configuration", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.camel.component.opa.OpaConfiguration", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
component configuration." },
-    "entrypoint": { "index": 2, "kind": "property", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed wh 
[...]
-    "evaluationMode": { "index": 3, "kind": "property", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a running [...]
-    "includeBody": { "index": 4, "kind": "property", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can b [...]
-    "includeHeaders": { "index": 5, "kind": "property", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defau [...]
-    "includeProperties": { "index": 6, "kind": "property", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all of [...]
-    "lazyStartProducer": { "index": 7, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "policyBundle": { "index": 8, "kind": "property", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {co [...]
-    "serverUrl": { "index": 9, "kind": "property", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defaul [...]
-    "autowiredEnabled": { "index": 10, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
-    "borrowTimeout": { "index": 11, "kind": "property", "displayName": "Borrow 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the e [...]
-    "connectionTimeout": { "index": 12, "kind": "property", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest mo [...]
-    "opaClient": { "index": 13, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 14, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
-    "requestTimeout": { "index": 15, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
-    "healthCheckConsumerEnabled": { "index": 16, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
-    "healthCheckProducerEnabled": { "index": 17, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
-    "bearerToken": { "index": 18, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
-    "failOpen": { "index": 19, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy cannot be evalua [...]
-    "sslContextParameters": { "index": 20, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
-    "useGlobalSslContextParameters": { "index": 21, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
+    "batch": { "index": 1, "kind": "property", "displayName": "Batch", 
"group": "producer", "label": "producer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Authorize a whole collection in one call. When 
enabled the producer expects a List body, evaluates one input  [...]
+    "configuration": { "index": 2, "kind": "property", "displayName": 
"Configuration", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.camel.component.opa.OpaConfiguration", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
component configuration." },
+    "entrypoint": { "index": 3, "kind": "property", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed wh 
[...]
+    "evaluationMode": { "index": 4, "kind": "property", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a running [...]
+    "includeBody": { "index": 5, "kind": "property", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can b [...]
+    "includeHeaders": { "index": 6, "kind": "property", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defau [...]
+    "includeProperties": { "index": 7, "kind": "property", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all of [...]
+    "lazyStartProducer": { "index": 8, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
+    "policyBundle": { "index": 9, "kind": "property", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {co [...]
+    "serverUrl": { "index": 10, "kind": "property", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defau [...]
+    "autowiredEnabled": { "index": 11, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching  [...]
+    "borrowTimeout": { "index": 12, "kind": "property", "displayName": "Borrow 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the e [...]
+    "connectionTimeout": { "index": 13, "kind": "property", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest mo [...]
+    "opaClient": { "index": 14, "kind": "property", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 15, "kind": "property", "displayName": "Pool Size", 
"group": "advanced", "label": "advanced", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thre [...]
+    "requestTimeout": { "index": 16, "kind": "property", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out  [...]
+    "healthCheckConsumerEnabled": { "index": 17, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
+    "healthCheckProducerEnabled": { "index": 18, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on produce [...]
+    "bearerToken": { "index": 19, "kind": "property", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance that [...]
+    "failOpen": { "index": 20, "kind": "property", "displayName": "Fail Open", 
"group": "security", "label": "security", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "security": "insecure:dev", "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to allow the exchange to proceed when 
the policy cannot be evalua [...]
+    "sslContextParameters": { "index": 21, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server in [...]
+    "useGlobalSslContextParameters": { "index": 22, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
   },
   "headers": {
     "CamelOpaDecisionAllow": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The allow\/deny verdict of the policy 
evaluation. Always overwritten by the component, so a value set by an inbound 
message never survives into the route.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#DECISION_ALLOW" },
     "CamelOpaDecision": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Object", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The raw decision document returned by OPA. 
Useful for policies that return more than a boolean, such as obligations, row 
filters or deny reasons.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#DECISION" },
     "CamelOpaPolicyPath": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The policy path that was evaluated. Set by the 
component for observability; it is not read as an input and cannot be used to 
select a different policy.", "constantName": 
"org.apache.camel.component.opa.OpaConstants#POLICY_PATH" },
-    "CamelOpaDecisionFailedOpen": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true only when the exchange 
proceeded because failOpen is enabled and the policy could not be evaluated - 
nothing authorized it. Absent on every decision an actual policy made, so a 
route or an audit trail can tell the  [...]
+    "CamelOpaDecisionFailedOpen": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true only when the exchange 
proceeded because failOpen is enabled and the policy could not be evaluated - 
nothing authorized it. Absent on every decision an actual policy made, so a 
route or an audit trail can tell the  [...]
+    "CamelOpaBatchDecision": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.List<Boolean>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The per-element 
allow\/deny verdicts of a batch evaluation (batch=true), as a List of Boolean 
parallel to the List body. Always overwritten by the component. An element 
whose evaluation could not be reached is denie [...]
   },
   "properties": {
     "policyPath": { "index": 0, "kind": "path", "displayName": "Policy Path", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Path of the Rego rule head 
to evaluate, relative to the OPA data document. For a rule named allow in a 
policy declaring package authz.orders, this is authz\/orders\/allow. The path 
is taken from the endpoint only: i [...]
     "allowKey": { "index": 1, "kind": "parameter", "displayName": "Allow Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "allow", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The key to read the allow\/deny verdict from 
when the policy returns an object rather than a plain  [...]
-    "entrypoint": { "index": 2, "kind": "parameter", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed w 
[...]
-    "evaluationMode": { "index": 3, "kind": "parameter", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a runnin [...]
-    "includeBody": { "index": 4, "kind": "parameter", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can  [...]
-    "includeHeaders": { "index": 5, "kind": "parameter", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defa [...]
-    "includeProperties": { "index": 6, "kind": "parameter", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all o [...]
-    "policyBundle": { "index": 7, "kind": "parameter", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {c [...]
-    "serverUrl": { "index": 8, "kind": "parameter", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defau [...]
-    "lazyStartProducer": { "index": 9, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
-    "borrowTimeout": { "index": 10, "kind": "parameter", "displayName": 
"Borrow Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the  [...]
-    "connectionTimeout": { "index": 11, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest m [...]
-    "opaClient": { "index": 12, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
-    "poolSize": { "index": 13, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
-    "requestTimeout": { "index": 14, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
-    "bearerToken": { "index": 15, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
-    "failOpen": { "index": 16, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy cannot be evalu [...]
-    "sslContextParameters": { "index": 17, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
+    "batch": { "index": 2, "kind": "parameter", "displayName": "Batch", 
"group": "producer", "label": "producer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Authorize a whole collection in one call. When 
enabled the producer expects a List body, evaluates one input [...]
+    "entrypoint": { "index": 3, "kind": "parameter", "displayName": 
"Entrypoint", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The compiled entrypoint to evaluate in wasm 
mode. This is not the same thing as the policy path: an entrypoint is fixed w 
[...]
+    "evaluationMode": { "index": 4, "kind": "parameter", "displayName": 
"Evaluation Mode", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "java.lang.String", "enum": [ "rest", "wasm" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"rest", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How the policy is evaluated. rest (the 
default) calls a runnin [...]
+    "includeBody": { "index": 5, "kind": "parameter", "displayName": "Include 
Body", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Whether to send the message body to OPA as 
part of the input document. Disabled by default: bodies can  [...]
+    "includeHeaders": { "index": 6, "kind": "parameter", "displayName": 
"Include Headers", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "*", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of message header names 
to send to OPA in the input document. The defa [...]
+    "includeProperties": { "index": 7, "kind": "parameter", "displayName": 
"Include Properties", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Comma-separated list of exchange property 
names to send to OPA in the input document, or {code } for all o [...]
+    "policyBundle": { "index": 8, "kind": "parameter", "displayName": "Policy 
Bundle", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The WebAssembly policy to evaluate in wasm 
mode, as produced by {code opa build -t wasm}. Accepts a {code file:}, {c [...]
+    "serverUrl": { "index": 9, "kind": "parameter", "displayName": "Server 
Url", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8181", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the OPA 
server, without the {code \/v1\/data} suffix. The defau [...]
+    "lazyStartProducer": { "index": 10, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
+    "borrowTimeout": { "index": 11, "kind": "parameter", "displayName": 
"Borrow Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long an exchange waits for a free 
WebAssembly policy instance in wasm mode before the  [...]
+    "connectionTimeout": { "index": 12, "kind": "parameter", "displayName": 
"Connection Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "duration", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "10000", 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "How long to wait for the 
connection to the OPA server to be established, in rest m [...]
+    "opaClient": { "index": 13, "kind": "parameter", "displayName": "Opa 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "com.styra.opa.OPAClient", "deprecated": false, 
"deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "An existing OPAClient to 
use. When set, serverUrl and bearerToken are ignored." },
+    "poolSize": { "index": 14, "kind": "parameter", "displayName": "Pool 
Size", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 8, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How many WebAssembly policy instances to pool 
in wasm mode. An instance carries mutable state and is not thr [...]
+    "requestTimeout": { "index": 15, "kind": "parameter", "displayName": 
"Request Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "How long to wait for the decision once 
connected, in rest mode. A request that times out [...]
+    "bearerToken": { "index": 16, "kind": "parameter", "displayName": "Bearer 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "Bearer token sent to the OPA server in the 
Authorization header, for an OPA instance tha [...]
+    "failOpen": { "index": 17, "kind": "parameter", "displayName": "Fail 
Open", "group": "security", "label": "security", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "security": "insecure:dev", "defaultValue": false, 
"configurationClass": "org.apache.camel.component.opa.OpaConfiguration", 
"configurationField": "configuration", "description": "Whether to allow the 
exchange to proceed when the policy cannot be evalu [...]
+    "sslContextParameters": { "index": 18, "kind": "parameter", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "TLS configuration for the connection to the 
OPA server i [...]
   }
 }
diff --git a/components/camel-opa/src/main/docs/opa-component.adoc 
b/components/camel-opa/src/main/docs/opa-component.adoc
index d674ffa40aed..9af5c30402db 100644
--- a/components/camel-opa/src/main/docs/opa-component.adoc
+++ b/components/camel-opa/src/main/docs/opa-component.adoc
@@ -180,6 +180,37 @@ boolean verdict read out of it:
 Both headers are written on every evaluation, so a verdict set by an inbound 
message never survives into the
 route.
 
+== Batch evaluation
+
+A route that splits a payload and authorizes each element pays one OPA 
round-trip per element. Set `batch=true` and
+hand the producer a `List` instead: it builds one input document per element - 
each element as the `body`, sharing
+the exchange's headers and properties - and evaluates them in a single call 
through OPA's batch API (the SDK falls
+back to sequential requests when the server does not implement it).
+
+[source,java]
+------------------------------------------------------------
+from("direct:orders")
+    // the body is a List of orders to authorize
+    .to("opa:authz/orders/allow?batch=true")
+    // CamelOpaBatchDecision is now a List<Boolean> parallel to the body
+    .process(dropTheDeniedOrders);
+------------------------------------------------------------
+
+The per-element verdicts arrive in `CamelOpaBatchDecision`, a `List<Boolean>` 
parallel to the input list: element
+_i_ is allowed when entry _i_ is `true`. Neither `CamelOpaDecisionAllow` nor 
`CamelOpaDecision` is set in batch
+mode - there is no single verdict, and no single decision document - and both 
are cleared on entry like the other
+decision headers, so a value an inbound message supplied never survives. 
`CamelOpaPolicyPath` *is* set, to the same
+value a single evaluation records, so tooling can read it either way.
+
+Fail-closed applies *per element*: an element whose evaluation could not be 
reached is denied (`false`), or allowed
+when `failOpen` is set, while every other element decides normally. The batch 
is never denied as a whole because
+one element failed, nor allowed because most of it succeeded. A call that 
fails entirely - the server could not be
+reached at all - fails the exchange rather than denying each element: it 
carries no verdict at all, not a list of
+`false`. Under `failOpen` that same failure allows every element instead.
+
+`batch` requires `evaluationMode=rest`: it saves the per-element HTTP 
round-trip, which has no meaning for in-process
+`wasm` evaluation, and the endpoint rejects the combination at startup.
+
 [#authorizing-an-identity]
 == Authorizing an identity
 
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
index 392e98257a4f..53fc17b783e7 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConfiguration.java
@@ -71,6 +71,9 @@ public class OpaConfiguration implements Cloneable {
     @UriParam(label = "security", security = "insecure:dev")
     private boolean failOpen;
 
+    @UriParam(label = "producer")
+    private boolean batch;
+
     @UriParam(label = "advanced",
               description = "An existing OPAClient to use. When set, serverUrl 
and bearerToken are ignored.")
     @Metadata(autowired = true)
@@ -281,6 +284,23 @@ public class OpaConfiguration implements Cloneable {
         this.failOpen = failOpen;
     }
 
+    public boolean isBatch() {
+        return batch;
+    }
+
+    /**
+     * Authorize a whole collection in one call. When enabled the producer 
expects a {@code List} body, evaluates one
+     * input document per element - each element as the {@code body}, sharing 
the exchange's headers and properties -
+     * and returns the per-element verdicts in the {@code 
CamelOpaBatchDecision} header, a {@code List<Boolean>}
+     * parallel to the input. An element whose evaluation could not be reached 
is denied, unless {@code failOpen} is
+     * set; the batch is never allowed or denied as a whole because one 
element failed. Only for
+     * {@code evaluationMode=rest}: it saves the per-element HTTP round-trip 
via OPA's batch API, which has no meaning
+     * for in-process {@code wasm}.
+     */
+    public void setBatch(boolean batch) {
+        this.batch = batch;
+    }
+
     /**
      * An already-configured {@link OPAClient} to use instead of letting the 
endpoint create one.
      */
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConstants.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConstants.java
index 60811d4b9b83..583b0dd6f49e 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConstants.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaConstants.java
@@ -47,6 +47,13 @@ public final class OpaConstants {
               javaType = "Boolean")
     public static final String DECISION_FAILED_OPEN = HEADER_PREFIX + 
"DecisionFailedOpen";
 
+    @Metadata(label = "producer",
+              description = "The per-element allow/deny verdicts of a batch 
evaluation (batch=true), as a List of"
+                            + " Boolean parallel to the List body. Always 
overwritten by the component. An element"
+                            + " whose evaluation could not be reached is 
denied, unless failOpen is set.",
+              javaType = "java.util.List<Boolean>")
+    public static final String BATCH_DECISION = HEADER_PREFIX + 
"BatchDecision";
+
     private OpaConstants() {
     }
 }
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
index 8a621193f8b4..2cadd776128a 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
@@ -71,6 +71,12 @@ public class OpaEndpoint extends DefaultEndpoint {
         super.doStart();
         String mode = configuration.getEvaluationMode();
         if (WASM_MODE.equalsIgnoreCase(mode)) {
+            if (configuration.isBatch()) {
+                throw new IllegalArgumentException(
+                        "batch is not supported with evaluationMode=wasm: it 
saves the per-element HTTP round-trip via"
+                                                   + " OPA's batch API, which 
has no meaning for in-process evaluation."
+                                                   + " Use 
evaluationMode=rest.");
+            }
             warnAboutIgnoredServerOptions();
             evaluator = createWasmEvaluator();
         } else if (!REST_MODE.equalsIgnoreCase(mode)) {
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaPolicyEvaluator.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaPolicyEvaluator.java
index e7ff69f0f5ea..f0e9d8eb57ec 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaPolicyEvaluator.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaPolicyEvaluator.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.opa;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -129,6 +130,106 @@ public abstract class OpaPolicyEvaluator {
      */
     protected abstract Object evaluateDecision(Map<String, Object> input) 
throws Exception;
 
+    /**
+     * Evaluates one input document per element in a single batch. The map is 
keyed so a result can be matched back to
+     * its element; each value carries either the decision or the failure that 
stopped it being reached. Only the REST
+     * evaluator implements this - wasm evaluates in-process, where batching 
saves nothing - so the default refuses.
+     */
+    protected Map<String, BatchElement> evaluateBatchDecisions(Map<String, 
Map<String, Object>> inputs) throws Exception {
+        throw new UnsupportedOperationException("batch evaluation is only 
supported with evaluationMode=rest");
+    }
+
+    /**
+     * Authorizes a list in one call and records the per-element verdicts in 
{@link OpaConstants#BATCH_DECISION}, a
+     * {@code List<Boolean>} parallel to the input.
+     * <p/>
+     * Fail-closed is per element: an element whose evaluation could not be 
reached is denied (or allowed under
+     * {@code failOpen}) while the others decide normally. Only a batch call 
that fails as a whole - the server could
+     * not be reached at all - denies (or, under {@code failOpen}, allows) 
every element.
+     */
+    public List<Boolean> evaluateBatch(Exchange exchange, List<?> elements) 
throws OpaPolicyEvaluationException {
+        clearDecisionHeaders(exchange);
+        // an empty list has nothing to authorize. Short-circuit before the 
engine call: an empty batch is a case the
+        // OPA SDK does not define, and letting it reach the server could turn 
"nothing to decide" into a whole-batch
+        // failure - and so, fail-closed, into an error thrown for an empty 
list. Answer it deterministically instead.
+        if (elements.isEmpty()) {
+            List<Boolean> verdicts = List.of();
+            setBatchDecisionHeaders(exchange, verdicts);
+            return verdicts;
+        }
+        Map<String, Map<String, Object>> inputs = new LinkedHashMap<>();
+        for (int i = 0; i < elements.size(); i++) {
+            inputs.put(Integer.toString(i), buildInput(exchange, 
elements.get(i), true));
+        }
+
+        List<Boolean> verdicts = new ArrayList<>(elements.size());
+        try {
+            Map<String, BatchElement> results = evaluateBatchDecisions(inputs);
+            for (int i = 0; i < elements.size(); i++) {
+                verdicts.add(verdictFor(i, results != null ? 
results.get(Integer.toString(i)) : null));
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new OpaPolicyEvaluationException(
+                    "Interrupted while evaluating policy " + getPolicyPath() + 
" in batch", exchange, e);
+        } catch (Exception e) {
+            // the batch call itself failed, so nothing was decided; fail 
closed for every element unless failOpen
+            if (!failOpen) {
+                throw new OpaPolicyEvaluationException(
+                        "Failed to evaluate policy " + getPolicyPath() + " in 
batch", exchange, e);
+            }
+            LOG.warn("Batch policy {} could not be evaluated, allowing all {} 
elements because failOpen is enabled."
+                     + " Reason: {}",
+                    getPolicyPath(), elements.size(), e.getMessage());
+            for (int i = 0; i < elements.size(); i++) {
+                verdicts.add(Boolean.TRUE);
+            }
+        }
+
+        setBatchDecisionHeaders(exchange, verdicts);
+        return verdicts;
+    }
+
+    private boolean verdictFor(int index, BatchElement element) {
+        if (element != null && element.succeeded()) {
+            return isAllowed(element.decision());
+        }
+        // a single element could not be reached: deny it (or allow under 
failOpen) without failing the whole batch
+        if (failOpen) {
+            String reason = element != null && element.failure() != null ? 
element.failure().getMessage() : "no result";
+            LOG.warn("Batch element {} of policy {} could not be evaluated, 
allowing it because failOpen is enabled."
+                     + " Reason: {}",
+                    index, getPolicyPath(), reason);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * One element's outcome in a batch: either a decision document, or the 
failure that stopped it being reached.
+     */
+    protected static final class BatchElement {
+        private final Object decision;
+        private final Exception failure;
+
+        BatchElement(Object decision, Exception failure) {
+            this.decision = decision;
+            this.failure = failure;
+        }
+
+        Object decision() {
+            return decision;
+        }
+
+        Exception failure() {
+            return failure;
+        }
+
+        boolean succeeded() {
+            return failure == null;
+        }
+    }
+
     protected String getPolicyPath() {
         return policyPath;
     }
@@ -137,6 +238,14 @@ public abstract class OpaPolicyEvaluator {
      * Builds the {@code input} document handed to OPA.
      */
     protected Map<String, Object> buildInput(Exchange exchange) {
+        return buildInput(exchange, exchange.getMessage().getBody(), 
includeBody);
+    }
+
+    /**
+     * Builds the OPA input document with an explicit body. Batch evaluation 
calls this once per list element, passing
+     * the element as the body so every element is authorized against the same 
shared headers and properties.
+     */
+    protected Map<String, Object> buildInput(Exchange exchange, Object body, 
boolean withBody) {
         Map<String, Object> input = new LinkedHashMap<>();
         Map<String, Object> headers = new LinkedHashMap<>();
         for (Map.Entry<String, Object> entry : 
exchange.getMessage().getHeaders().entrySet()) {
@@ -169,8 +278,8 @@ public abstract class OpaPolicyEvaluator {
                 input.put("properties", properties);
             }
         }
-        if (includeBody) {
-            input.put("body", toJsonSafe(exchange, 
exchange.getMessage().getBody()));
+        if (withBody) {
+            input.put("body", toJsonSafe(exchange, body));
         }
         input.put("exchangeId", exchange.getExchangeId());
         if (exchange.getFromRouteId() != null) {
@@ -240,6 +349,7 @@ public abstract class OpaPolicyEvaluator {
         // as attacker-settable as the verdict itself: left in place, a sender 
could preload it false and make a
         // fail-open read as a decision a policy actually made
         message.removeHeader(OpaConstants.DECISION_FAILED_OPEN);
+        message.removeHeader(OpaConstants.BATCH_DECISION);
     }
 
     private void setDecisionHeaders(Exchange exchange, Object decision, 
boolean allowed) {
@@ -249,6 +359,17 @@ public abstract class OpaPolicyEvaluator {
         exchange.getMessage().setHeader(OpaConstants.POLICY_PATH, policyPath);
     }
 
+    /**
+     * Records the batch outcome on the exchange: the per-element verdict 
list, and the policy path, so that tooling
+     * reading {@link OpaConstants#POLICY_PATH} sees the same value in batch 
mode as it does after a single evaluation.
+     * As in {@link #evaluate}, a fail-closed batch failure never reaches 
here, leaving the exchange carrying no
+     * verdict.
+     */
+    private void setBatchDecisionHeaders(Exchange exchange, List<Boolean> 
verdicts) {
+        exchange.getMessage().setHeader(OpaConstants.BATCH_DECISION, verdicts);
+        exchange.getMessage().setHeader(OpaConstants.POLICY_PATH, policyPath);
+    }
+
     private static boolean isIncluded(Set<String> filter, String name) {
         return filter == null || filter.contains(name);
     }
@@ -277,7 +398,8 @@ public abstract class OpaPolicyEvaluator {
         return OpaConstants.DECISION_ALLOW.equalsIgnoreCase(name)
                 || OpaConstants.DECISION.equalsIgnoreCase(name)
                 || OpaConstants.POLICY_PATH.equalsIgnoreCase(name)
-                || OpaConstants.DECISION_FAILED_OPEN.equalsIgnoreCase(name);
+                || OpaConstants.DECISION_FAILED_OPEN.equalsIgnoreCase(name)
+                || OpaConstants.BATCH_DECISION.equalsIgnoreCase(name);
     }
 
     /**
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
index 110d8367f88f..0dbaa901a1ef 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaProducer.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.opa;
 
+import java.util.List;
+
 import org.apache.camel.Exchange;
 import org.apache.camel.health.HealthCheckHelper;
 import org.apache.camel.health.WritableHealthCheckRepository;
@@ -78,6 +80,17 @@ public class OpaProducer extends DefaultProducer {
     public void process(Exchange exchange) throws Exception {
         // the verdict is reported through the decision headers, so that the 
route can act on it with a
         // filter or a choice; the body is left untouched
-        getEndpoint().getEvaluator().evaluate(exchange);
+        OpaPolicyEvaluator evaluator = getEndpoint().getEvaluator();
+        if (getEndpoint().getConfiguration().isBatch()) {
+            Object body = exchange.getMessage().getBody();
+            if (!(body instanceof List<?> elements)) {
+                throw new IllegalArgumentException(
+                        "batch=true requires a List body, but the body was "
+                                                   + (body == null ? "null" : 
body.getClass().getName()));
+            }
+            evaluator.evaluateBatch(exchange, elements);
+        } else {
+            evaluator.evaluate(exchange);
+        }
     }
 }
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaRestEvaluator.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaRestEvaluator.java
index 10a67c19eecb..53b7ccb365c5 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaRestEvaluator.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaRestEvaluator.java
@@ -16,11 +16,13 @@
  */
 package org.apache.camel.component.opa;
 
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import javax.net.ssl.SSLContext;
 
 import com.styra.opa.OPAClient;
+import com.styra.opa.OPAResult;
 import org.apache.camel.util.ObjectHelper;
 
 /**
@@ -78,4 +80,28 @@ public class OpaRestEvaluator extends OpaPolicyEvaluator 
implements AutoCloseabl
         // the WASM engine is made to behave identically
         return client.evaluate(getPolicyPath(), input, Object.class);
     }
+
+    @Override
+    protected Map<String, BatchElement> evaluateBatchDecisions(Map<String, 
Map<String, Object>> inputs)
+            throws Exception {
+        // one HTTP round-trip via OPA's batch endpoint; the SDK falls back to 
sequential calls if the server does
+        // not implement it. Each entry carries its own decision or its own 
failure, so one bad element does not sink
+        // the batch.
+        Map<String, Object> batchInputs = new LinkedHashMap<>(inputs);
+        Map<String, OPAResult> results = client.evaluateBatch(getPolicyPath(), 
batchInputs);
+        Map<String, BatchElement> outcomes = new LinkedHashMap<>();
+        for (Map.Entry<String, OPAResult> entry : results.entrySet()) {
+            OPAResult result = entry.getValue();
+            if (result != null && result.success()) {
+                outcomes.put(entry.getKey(), new 
BatchElement(result.getValue(), null));
+            } else {
+                Exception failure = result != null ? result.getException() : 
null;
+                if (failure == null) {
+                    failure = new IllegalStateException("no result returned 
for batch element " + entry.getKey());
+                }
+                outcomes.put(entry.getKey(), new BatchElement(null, failure));
+            }
+        }
+        return outcomes;
+    }
 }
diff --git 
a/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaBatchEvaluationTest.java
 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaBatchEvaluationTest.java
new file mode 100644
index 000000000000..ab5e51c91135
--- /dev/null
+++ 
b/components/camel-opa/src/test/java/org/apache/camel/component/opa/OpaBatchEvaluationTest.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.opa;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.styra.opa.OPAClient;
+import com.styra.opa.OPAException;
+import com.styra.opa.OPAResult;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Batch evaluation authorizes a List body in one call and reports a 
per-element verdict list. Fail-closed is per
+ * element: an element that could not be evaluated is denied (or allowed under 
failOpen) while its neighbours decide
+ * normally (CAMEL-24740).
+ */
+public class OpaBatchEvaluationTest extends CamelTestSupport {
+
+    private static final String PATH = "authz/allow";
+
+    @BindToRegistry("opaClient")
+    private final OPAClient client = mock(OPAClient.class);
+
+    private OPAResult failed() {
+        // a batch element whose evaluation could not be reached: the server 
returned a result carrying an error
+        OPAResult result = mock(OPAResult.class);
+        when(result.success()).thenReturn(false);
+        return result;
+    }
+
+    private void stubBatch(Map<String, OPAResult> results) throws Exception {
+        when(client.evaluateBatch(eq(PATH), anyMap())).thenReturn(results);
+    }
+
+    @Test
+    void reportsAVerdictParallelToEachElement() throws Exception {
+        Map<String, OPAResult> results = new LinkedHashMap<>();
+        results.put("0", new OPAResult(Boolean.TRUE));
+        results.put("1", new OPAResult(Boolean.FALSE));
+        results.put("2", new OPAResult(Boolean.TRUE));
+        stubBatch(results);
+
+        Exchange out = template.request("opa:" + PATH + 
"?opaClient=#opaClient&batch=true",
+                e -> e.getMessage().setBody(List.of("alice", "mallory", 
"carol")));
+
+        assertThat(out.getException()).isNull();
+        assertThat(out.getMessage().getHeader(OpaConstants.BATCH_DECISION, 
List.class))
+                .containsExactly(true, false, true);
+        // batch mode must set the policy-path header too, so observability 
tooling reads the same
+        // CamelOpaPolicyPath as it does after a single evaluation
+        assertThat(out.getMessage().getHeader(OpaConstants.POLICY_PATH, 
String.class)).isEqualTo(PATH);
+    }
+
+    @Test
+    void deniesAFailedElementButLetsItsNeighboursDecide() throws Exception {
+        Map<String, OPAResult> results = new LinkedHashMap<>();
+        results.put("0", new OPAResult(Boolean.TRUE));
+        results.put("1", failed());
+        results.put("2", new OPAResult(Boolean.TRUE));
+        stubBatch(results);
+
+        Exchange out = template.request("opa:" + PATH + 
"?opaClient=#opaClient&batch=true",
+                e -> e.getMessage().setBody(List.of("a", "b", "c")));
+
+        // the middle element is denied because it could not be evaluated, not 
because the whole batch failed
+        assertThat(out.getException()).isNull();
+        assertThat(out.getMessage().getHeader(OpaConstants.BATCH_DECISION, 
List.class))
+                .containsExactly(true, false, true);
+    }
+
+    @Test
+    void allowsAFailedElementUnderFailOpen() throws Exception {
+        Map<String, OPAResult> results = new LinkedHashMap<>();
+        results.put("0", new OPAResult(Boolean.TRUE));
+        results.put("1", failed());
+        results.put("2", new OPAResult(Boolean.FALSE));
+        stubBatch(results);
+
+        Exchange out = template.request("opa:" + PATH + 
"?opaClient=#opaClient&batch=true&failOpen=true",
+                e -> e.getMessage().setBody(List.of("a", "b", "c")));
+
+        // failOpen turns the unreachable element into an allow; the genuine 
deny at index 2 is unaffected
+        assertThat(out.getException()).isNull();
+        assertThat(out.getMessage().getHeader(OpaConstants.BATCH_DECISION, 
List.class))
+                .containsExactly(true, true, false);
+    }
+
+    @Test
+    void requiresAListBody() {
+        Exchange out = template.request("opa:" + PATH + 
"?opaClient=#opaClient&batch=true",
+                e -> e.getMessage().setBody("not a list"));
+
+        
assertThat(out.getException()).isInstanceOf(IllegalArgumentException.class);
+        assertThat(out.getException().getMessage()).contains("List");
+    }
+
+    @Test
+    void rejectsBatchInWasmModeAtStartup() {
+        assertThatThrownBy(() -> context.getEndpoint(
+                "opa:" + PATH + 
"?evaluationMode=wasm&policyBundle=classpath:authz.wasm&batch=true").start())
+                .isInstanceOf(Exception.class)
+                .hasMessageContaining("batch");
+    }
+
+    @Test
+    void reportsAnEmptyVerdictListForAnEmptyBatch() throws Exception {
+        // an empty list is answered without calling the SDK: an empty batch 
input is undefined there, so the
+        // short-circuit makes it a deterministic empty verdict list. The 
policy-path header is still set.
+        Exchange out = template.request("opa:" + PATH + 
"?opaClient=#opaClient&batch=true",
+                e -> e.getMessage().setBody(List.of()));
+
+        assertThat(out.getException()).isNull();
+        assertThat(out.getMessage().getHeader(OpaConstants.BATCH_DECISION, 
List.class)).isEmpty();
+        assertThat(out.getMessage().getHeader(OpaConstants.POLICY_PATH, 
String.class)).isEqualTo(PATH);
+        verify(client, never()).evaluateBatch(anyString(), anyMap());
+    }
+
+    @Test
+    void failsClosedWhenTheWholeBatchCannotBeEvaluated() throws Exception {
+        // the batch call itself fails - the server could not be reached at 
all - so nothing was decided. With
+        // failOpen off, every element is denied by failing the exchange, not 
by returning a verdict list.
+        when(client.evaluateBatch(eq(PATH), anyMap())).thenThrow(new 
OPAException("connection refused"));
+
+        Exchange out = template.request("opa:" + PATH + 
"?opaClient=#opaClient&batch=true",
+                e -> e.getMessage().setBody(List.of("a", "b")));
+
+        assertThat(out.getException())
+                .isInstanceOf(OpaPolicyEvaluationException.class)
+                .hasMessageContaining("in batch");
+        // fail-closed leaves no verdict on the exchange, mirroring the 
single-evaluation failure path
+        
assertThat(out.getMessage().getHeader(OpaConstants.BATCH_DECISION)).isNull();
+    }
+
+    @Test
+    void allowsEveryElementUnderFailOpenWhenTheWholeBatchFails() throws 
Exception {
+        // failOpen turns a whole-batch failure into an allow for every 
element, parallel to the single-evaluation
+        // failOpen path
+        when(client.evaluateBatch(eq(PATH), anyMap())).thenThrow(new 
OPAException("connection refused"));
+
+        Exchange out = template.request("opa:" + PATH + 
"?opaClient=#opaClient&batch=true&failOpen=true",
+                e -> e.getMessage().setBody(List.of("a", "b", "c")));
+
+        assertThat(out.getException()).isNull();
+        assertThat(out.getMessage().getHeader(OpaConstants.BATCH_DECISION, 
List.class))
+                .containsExactly(true, true, true);
+    }
+}
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
index 3b1c544f969a..dbf83c3b4e6a 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/OpaComponentBuilderFactory.java
@@ -74,6 +74,32 @@ public interface OpaComponentBuilderFactory {
             return this;
         }
     
+        
+        /**
+         * Authorize a whole collection in one call. When enabled the producer
+         * expects a List body, evaluates one input document per element - each
+         * element as the body, sharing the exchange's headers and properties -
+         * and returns the per-element verdicts in the CamelOpaBatchDecision
+         * header, a List parallel to the input. An element whose evaluation
+         * could not be reached is denied, unless failOpen is set; the batch is
+         * never allowed or denied as a whole because one element failed. Only
+         * for {code evaluationMode=rest}: it saves the per-element HTTP
+         * round-trip via OPA's batch API, which has no meaning for in-process
+         * wasm.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: producer
+         * 
+         * @param batch the value to set
+         * @return the dsl builder
+         */
+        default OpaComponentBuilder batch(boolean batch) {
+            doSetProperty("batch", batch);
+            return this;
+        }
+    
         /**
          * The component configuration.
          * 
@@ -519,6 +545,7 @@ public interface OpaComponentBuilderFactory {
                 Object value) {
             switch (name) {
             case "allowKey": getOrCreateConfiguration((OpaComponent) 
component).setAllowKey((java.lang.String) value); return true;
+            case "batch": getOrCreateConfiguration((OpaComponent) 
component).setBatch((boolean) value); return true;
             case "configuration": ((OpaComponent) 
component).setConfiguration((org.apache.camel.component.opa.OpaConfiguration) 
value); return true;
             case "entrypoint": getOrCreateConfiguration((OpaComponent) 
component).setEntrypoint((java.lang.String) value); return true;
             case "evaluationMode": getOrCreateConfiguration((OpaComponent) 
component).setEvaluationMode((java.lang.String) value); return true;
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
index d71b57df2d9f..693ad42de71c 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpaEndpointBuilderFactory.java
@@ -65,6 +65,54 @@ public interface OpaEndpointBuilderFactory {
             doSetProperty("allowKey", allowKey);
             return this;
         }
+        /**
+         * Authorize a whole collection in one call. When enabled the producer
+         * expects a List body, evaluates one input document per element - each
+         * element as the body, sharing the exchange's headers and properties -
+         * and returns the per-element verdicts in the CamelOpaBatchDecision
+         * header, a List parallel to the input. An element whose evaluation
+         * could not be reached is denied, unless failOpen is set; the batch is
+         * never allowed or denied as a whole because one element failed. Only
+         * for {code evaluationMode=rest}: it saves the per-element HTTP
+         * round-trip via OPA's batch API, which has no meaning for in-process
+         * wasm.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: producer
+         * 
+         * @param batch the value to set
+         * @return the dsl builder
+         */
+        default OpaEndpointBuilder batch(boolean batch) {
+            doSetProperty("batch", batch);
+            return this;
+        }
+        /**
+         * Authorize a whole collection in one call. When enabled the producer
+         * expects a List body, evaluates one input document per element - each
+         * element as the body, sharing the exchange's headers and properties -
+         * and returns the per-element verdicts in the CamelOpaBatchDecision
+         * header, a List parallel to the input. An element whose evaluation
+         * could not be reached is denied, unless failOpen is set; the batch is
+         * never allowed or denied as a whole because one element failed. Only
+         * for {code evaluationMode=rest}: it saves the per-element HTTP
+         * round-trip via OPA's batch API, which has no meaning for in-process
+         * wasm.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: producer
+         * 
+         * @param batch the value to set
+         * @return the dsl builder
+         */
+        default OpaEndpointBuilder batch(String batch) {
+            doSetProperty("batch", batch);
+            return this;
+        }
         /**
          * The compiled entrypoint to evaluate in wasm mode. This is not the
          * same thing as the policy path: an entrypoint is fixed when the 
bundle
@@ -690,6 +738,21 @@ public interface OpaEndpointBuilderFactory {
         public String opaDecisionFailedOpen() {
             return "CamelOpaDecisionFailedOpen";
         }
+        /**
+         * The per-element allow/deny verdicts of a batch evaluation
+         * (batch=true), as a List of Boolean parallel to the List body. Always
+         * overwritten by the component. An element whose evaluation could not
+         * be reached is denied, unless failOpen is set.
+         * 
+         * The option is a: {@code java.util.List<Boolean>} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code OpaBatchDecision}.
+         */
+        public String opaBatchDecision() {
+            return "CamelOpaBatchDecision";
+        }
     }
     static OpaEndpointBuilder endpointBuilder(String componentName, String 
path) {
         class OpaEndpointBuilderImpl extends AbstractEndpointBuilder 
implements OpaEndpointBuilder, AdvancedOpaEndpointBuilder {

Reply via email to