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

davsclaus 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 1d2cba763707 CAMEL-24730: camel-spiffe - do not let inbound headers 
choose the operation or the validated audience
1d2cba763707 is described below

commit 1d2cba7637072aece5aca8f83a6cdb904e08e1e8
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Sep 15 06:52:12 2026 +0200

    CAMEL-24730: camel-spiffe - do not let inbound headers choose the operation 
or the validated audience
    
    SpiffeProducer read both the operation and the audience from message 
headers in
    preference to the endpoint configuration. For validateJwtSvid the audience 
is the
    check itself, so CamelSpiffeAudience let a token minted for another service 
validate
    successfully, and CamelSpiffeOperation could turn a validator endpoint into 
a minter
    that returned the workload's own JWT-SVID.
    
    validateJwtSvid now uses the configured audience only (fetchJwtSvid still 
honours the
    header, where a per-message audience is legitimate). A new 
allowOperationHeader
    option, default false and marked security = "insecure:dev", gates
    CamelSpiffeOperation so camel.main.profile=prod flags routes that enable 
it. Header
    javadoc and a Security notes docs section describe when each header is 
honoured.
    
    main only: camel-spiffe is new in the unreleased 4.23.0.
    
    Closes #26420
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
---
 .../apache/camel/catalog/components/spiffe.json    |  10 +-
 .../camel/catalog/docs/spiffe-component.adoc       |  19 ++++
 .../spiffe/SpiffeComponentConfigurer.java          |   6 ++
 .../component/spiffe/SpiffeEndpointConfigurer.java |   6 ++
 .../component/spiffe/SpiffeEndpointUriFactory.java |   3 +-
 .../org/apache/camel/component/spiffe/spiffe.json  |  10 +-
 .../src/main/docs/spiffe-component.adoc            |  19 ++++
 .../component/spiffe/SpiffeConfiguration.java      |  18 ++++
 .../camel/component/spiffe/SpiffeConstants.java    |   9 +-
 .../camel/component/spiffe/SpiffeProducer.java     |  32 ++++--
 .../component/spiffe/SpiffeHeaderOverrideTest.java | 111 +++++++++++++++++++++
 .../java/org/apache/camel/util/SecurityUtils.java  |   1 +
 .../dsl/SpiffeComponentBuilderFactory.java         |  22 ++++
 .../endpoint/dsl/SpiffeEndpointBuilderFactory.java |  48 ++++++++-
 14 files changed, 294 insertions(+), 20 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
index 82dc8b9cc87d..1b8c1a3c3731 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
@@ -30,11 +30,12 @@
     "operation": { "index": 3, "kind": "property", "displayName": "Operation", 
"group": "producer", "label": "", "required": false, "type": "enum", 
"javaType": "org.apache.camel.component.spiffe.SpiffeOperation", "enum": [ 
"fetchX509Svid", "fetchJwtSvid", "validateJwtSvid" ], "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "fetchX509Svid", 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "descr [...]
     "autowiredEnabled": { "index": 4, "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 t [...]
     "workloadApiClient": { "index": 5, "kind": "property", "displayName": 
"Workload Api Client", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "io.spiffe.workloadapi.WorkloadApiClient", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "description": "An existing 
WorkloadApiClient to use. When set, [...]
-    "spiffeSocketPath": { "index": 6, "kind": "property", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock} [...]
+    "allowOperationHeader": { "index": 6, "kind": "property", "displayName": 
"Allow Operation Header", "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.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "Whether the CamelSpiffeOperation header may 
[...]
+    "spiffeSocketPath": { "index": 7, "kind": "property", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock} [...]
   },
   "headers": {
-    "CamelSpiffeOperation": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.spiffe.SpiffeOperation or String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Overrides the operation to be used by the producer.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#OPERATION" },
-    "CamelSpiffeAudience": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The comma-separated audience(s) for the 
fetchJwtSvid and validateJwtSvid operations.", "constantName": 
"org.apache.camel.component.spiffe.SpiffeConstants#AUDIENCE" },
+    "CamelSpiffeOperation": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.spiffe.SpiffeOperation or String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Overrides the operation to be used by the producer. Ignored 
unless the endpoint sets allowOperationHeader=true, because the operation 
decides whether the endpoint validates a token [...]
+    "CamelSpiffeAudience": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The comma-separated audience(s) for the 
fetchJwtSvid operation. Ignored by validateJwtSvid, which always validates 
against the configured audience: there the audience is the check that binds the 
token to this workload, not a parameter [...]
     "CamelSpiffeToken": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The JWT-SVID token to validate, for the 
validateJwtSvid operation.", "constantName": 
"org.apache.camel.component.spiffe.SpiffeConstants#TOKEN" },
     "CamelSpiffeSpiffeId": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The SPIFFE ID of the returned SVID.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#SPIFFE_ID" },
     "CamelSpiffeExpiry": { "index": 4, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.Date", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The expiry of the returned JWT-SVID.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#EXPIRY" }
@@ -45,6 +46,7 @@
     "operation": { "index": 2, "kind": "parameter", "displayName": 
"Operation", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "org.apache.camel.component.spiffe.SpiffeOperation", 
"enum": [ "fetchX509Svid", "fetchJwtSvid", "validateJwtSvid" ], "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": "fetchX509Svid", 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "desc [...]
     "lazyStartProducer": { "index": 3, "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 [...]
     "workloadApiClient": { "index": 4, "kind": "parameter", "displayName": 
"Workload Api Client", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "io.spiffe.workloadapi.WorkloadApiClient", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "description": "An existing 
WorkloadApiClient to use. When set [...]
-    "spiffeSocketPath": { "index": 5, "kind": "parameter", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock [...]
+    "allowOperationHeader": { "index": 5, "kind": "parameter", "displayName": 
"Allow Operation Header", "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.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "Whether the CamelSpiffeOperation header ma 
[...]
+    "spiffeSocketPath": { "index": 6, "kind": "parameter", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock [...]
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spiffe-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spiffe-component.adoc
index 93f8dafde435..17b45a0a1888 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spiffe-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spiffe-component.adoc
@@ -117,3 +117,22 @@ from("direct:start")
 ------------------------------------------------------------
 
 include::spring-boot:partial$starter.adoc[]
+
+== Security notes
+
+* *The operation comes from the endpoint.* `CamelSpiffeOperation` is ignored 
unless the endpoint sets
+  `allowOperationHeader=true`. The operation decides whether this endpoint 
*validates* a token or *mints* one, so a
+  message able to set it could turn a validator into an endpoint that hands 
out this workload's own JWT-SVID.
+* *A validation always uses the configured audience.* `CamelSpiffeAudience` is 
honoured by `fetchJwtSvid`, where the
+  audience is a genuine per-message parameter ("mint me a token for X"), and 
ignored by `validateJwtSvid`, where the
+  audience is the check that binds the token to this workload. Letting a 
message choose it would allow a JWT-SVID
+  minted for a different service to validate successfully.
+* *Strip the component's headers on untrusted ingress.* As with any Camel 
component, a consumer that does not apply
+  a `HeaderFilterStrategy` blocking `Camel*` lets a sender populate the header 
map. Call
+  `removeHeaders("CamelSpiffe*")` before the `spiffe:` endpoint when the 
message comes from an untrusted producer.
+* *Key material reaches the message.* `fetchX509Svid` places an `X509Svid` - 
which carries the private key - on the
+  body, and `fetchJwtSvid` places the bearer token. Do not log or trace the 
body for those operations.
+* *Constrain the peer.* `SpiffeSSLContextParameters` requires either an 
`acceptedSpiffeIds` allow-list or
+  `acceptAnySpiffeId=true`; it fails closed when neither is given. Prefer the 
allow-list -
+  `acceptAnySpiffeId` accepts any SVID that chains to the trust bundle, which 
authenticates the trust domain but not
+  the peer.
diff --git 
a/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeComponentConfigurer.java
 
b/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeComponentConfigurer.java
index 67a411d84847..c5f39f05820e 100644
--- 
a/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeComponentConfigurer.java
+++ 
b/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeComponentConfigurer.java
@@ -30,6 +30,8 @@ public class SpiffeComponentConfigurer extends 
PropertyConfigurerSupport impleme
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
         SpiffeComponent target = (SpiffeComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowoperationheader":
+        case "allowOperationHeader": 
getOrCreateConfiguration(target).setAllowOperationHeader(property(camelContext, 
boolean.class, value)); return true;
         case "audience": 
getOrCreateConfiguration(target).setAudience(property(camelContext, 
java.lang.String.class, value)); return true;
         case "autowiredenabled":
         case "autowiredEnabled": 
target.setAutowiredEnabled(property(camelContext, boolean.class, value)); 
return true;
@@ -53,6 +55,8 @@ public class SpiffeComponentConfigurer extends 
PropertyConfigurerSupport impleme
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowoperationheader":
+        case "allowOperationHeader": return boolean.class;
         case "audience": return java.lang.String.class;
         case "autowiredenabled":
         case "autowiredEnabled": return boolean.class;
@@ -72,6 +76,8 @@ public class SpiffeComponentConfigurer extends 
PropertyConfigurerSupport impleme
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         SpiffeComponent target = (SpiffeComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowoperationheader":
+        case "allowOperationHeader": return 
getOrCreateConfiguration(target).isAllowOperationHeader();
         case "audience": return getOrCreateConfiguration(target).getAudience();
         case "autowiredenabled":
         case "autowiredEnabled": return target.isAutowiredEnabled();
diff --git 
a/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointConfigurer.java
 
b/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointConfigurer.java
index afa1dd20067f..0eedcc77671a 100644
--- 
a/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointConfigurer.java
+++ 
b/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointConfigurer.java
@@ -23,6 +23,8 @@ public class SpiffeEndpointConfigurer extends 
PropertyConfigurerSupport implemen
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
         SpiffeEndpoint target = (SpiffeEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowoperationheader":
+        case "allowOperationHeader": 
target.getConfiguration().setAllowOperationHeader(property(camelContext, 
boolean.class, value)); return true;
         case "audience": 
target.getConfiguration().setAudience(property(camelContext, 
java.lang.String.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
@@ -43,6 +45,8 @@ public class SpiffeEndpointConfigurer extends 
PropertyConfigurerSupport implemen
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowoperationheader":
+        case "allowOperationHeader": return boolean.class;
         case "audience": return java.lang.String.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
@@ -59,6 +63,8 @@ public class SpiffeEndpointConfigurer extends 
PropertyConfigurerSupport implemen
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         SpiffeEndpoint target = (SpiffeEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowoperationheader":
+        case "allowOperationHeader": return 
target.getConfiguration().isAllowOperationHeader();
         case "audience": return target.getConfiguration().getAudience();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
diff --git 
a/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointUriFactory.java
 
b/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointUriFactory.java
index ad61739085cb..38ae3005bca9 100644
--- 
a/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointUriFactory.java
+++ 
b/components/camel-spiffe/src/generated/java/org/apache/camel/component/spiffe/SpiffeEndpointUriFactory.java
@@ -24,7 +24,8 @@ public class SpiffeEndpointUriFactory extends 
org.apache.camel.support.component
     private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(6);
+        Set<String> props = new HashSet<>(7);
+        props.add("allowOperationHeader");
         props.add("audience");
         props.add("label");
         props.add("lazyStartProducer");
diff --git 
a/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
 
b/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
index 82dc8b9cc87d..1b8c1a3c3731 100644
--- 
a/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
+++ 
b/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
@@ -30,11 +30,12 @@
     "operation": { "index": 3, "kind": "property", "displayName": "Operation", 
"group": "producer", "label": "", "required": false, "type": "enum", 
"javaType": "org.apache.camel.component.spiffe.SpiffeOperation", "enum": [ 
"fetchX509Svid", "fetchJwtSvid", "validateJwtSvid" ], "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "fetchX509Svid", 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "descr [...]
     "autowiredEnabled": { "index": 4, "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 t [...]
     "workloadApiClient": { "index": 5, "kind": "property", "displayName": 
"Workload Api Client", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "io.spiffe.workloadapi.WorkloadApiClient", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "description": "An existing 
WorkloadApiClient to use. When set, [...]
-    "spiffeSocketPath": { "index": 6, "kind": "property", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock} [...]
+    "allowOperationHeader": { "index": 6, "kind": "property", "displayName": 
"Allow Operation Header", "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.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "Whether the CamelSpiffeOperation header may 
[...]
+    "spiffeSocketPath": { "index": 7, "kind": "property", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock} [...]
   },
   "headers": {
-    "CamelSpiffeOperation": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.spiffe.SpiffeOperation or String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Overrides the operation to be used by the producer.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#OPERATION" },
-    "CamelSpiffeAudience": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The comma-separated audience(s) for the 
fetchJwtSvid and validateJwtSvid operations.", "constantName": 
"org.apache.camel.component.spiffe.SpiffeConstants#AUDIENCE" },
+    "CamelSpiffeOperation": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.spiffe.SpiffeOperation or String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Overrides the operation to be used by the producer. Ignored 
unless the endpoint sets allowOperationHeader=true, because the operation 
decides whether the endpoint validates a token [...]
+    "CamelSpiffeAudience": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The comma-separated audience(s) for the 
fetchJwtSvid operation. Ignored by validateJwtSvid, which always validates 
against the configured audience: there the audience is the check that binds the 
token to this workload, not a parameter [...]
     "CamelSpiffeToken": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The JWT-SVID token to validate, for the 
validateJwtSvid operation.", "constantName": 
"org.apache.camel.component.spiffe.SpiffeConstants#TOKEN" },
     "CamelSpiffeSpiffeId": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The SPIFFE ID of the returned SVID.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#SPIFFE_ID" },
     "CamelSpiffeExpiry": { "index": 4, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.Date", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The expiry of the returned JWT-SVID.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#EXPIRY" }
@@ -45,6 +46,7 @@
     "operation": { "index": 2, "kind": "parameter", "displayName": 
"Operation", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "org.apache.camel.component.spiffe.SpiffeOperation", 
"enum": [ "fetchX509Svid", "fetchJwtSvid", "validateJwtSvid" ], "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": "fetchX509Svid", 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "desc [...]
     "lazyStartProducer": { "index": 3, "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 [...]
     "workloadApiClient": { "index": 4, "kind": "parameter", "displayName": 
"Workload Api Client", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "io.spiffe.workloadapi.WorkloadApiClient", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": "org.apache.camel.component.spiffe.SpiffeConfiguration", 
"configurationField": "configuration", "description": "An existing 
WorkloadApiClient to use. When set [...]
-    "spiffeSocketPath": { "index": 5, "kind": "parameter", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock [...]
+    "allowOperationHeader": { "index": 5, "kind": "parameter", "displayName": 
"Allow Operation Header", "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.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "Whether the CamelSpiffeOperation header ma 
[...]
+    "spiffeSocketPath": { "index": 6, "kind": "parameter", "displayName": 
"Spiffe Socket Path", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The address of the SPIFFE Workload API 
endpoint (for example {code unix:\/\/\/tmp\/agent.sock [...]
   }
 }
diff --git a/components/camel-spiffe/src/main/docs/spiffe-component.adoc 
b/components/camel-spiffe/src/main/docs/spiffe-component.adoc
index 93f8dafde435..17b45a0a1888 100644
--- a/components/camel-spiffe/src/main/docs/spiffe-component.adoc
+++ b/components/camel-spiffe/src/main/docs/spiffe-component.adoc
@@ -117,3 +117,22 @@ from("direct:start")
 ------------------------------------------------------------
 
 include::spring-boot:partial$starter.adoc[]
+
+== Security notes
+
+* *The operation comes from the endpoint.* `CamelSpiffeOperation` is ignored 
unless the endpoint sets
+  `allowOperationHeader=true`. The operation decides whether this endpoint 
*validates* a token or *mints* one, so a
+  message able to set it could turn a validator into an endpoint that hands 
out this workload's own JWT-SVID.
+* *A validation always uses the configured audience.* `CamelSpiffeAudience` is 
honoured by `fetchJwtSvid`, where the
+  audience is a genuine per-message parameter ("mint me a token for X"), and 
ignored by `validateJwtSvid`, where the
+  audience is the check that binds the token to this workload. Letting a 
message choose it would allow a JWT-SVID
+  minted for a different service to validate successfully.
+* *Strip the component's headers on untrusted ingress.* As with any Camel 
component, a consumer that does not apply
+  a `HeaderFilterStrategy` blocking `Camel*` lets a sender populate the header 
map. Call
+  `removeHeaders("CamelSpiffe*")` before the `spiffe:` endpoint when the 
message comes from an untrusted producer.
+* *Key material reaches the message.* `fetchX509Svid` places an `X509Svid` - 
which carries the private key - on the
+  body, and `fetchJwtSvid` places the bearer token. Do not log or trace the 
body for those operations.
+* *Constrain the peer.* `SpiffeSSLContextParameters` requires either an 
`acceptedSpiffeIds` allow-list or
+  `acceptAnySpiffeId=true`; it fails closed when neither is given. Prefer the 
allow-list -
+  `acceptAnySpiffeId` accepts any SVID that chains to the trust bundle, which 
authenticates the trust domain but not
+  the peer.
diff --git 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConfiguration.java
 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConfiguration.java
index e19fbe9c5eb3..f34dad7f40e3 100644
--- 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConfiguration.java
+++ 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConfiguration.java
@@ -34,6 +34,9 @@ public class SpiffeConfiguration implements Cloneable {
     @UriParam
     private String audience;
 
+    @UriParam(label = "security", defaultValue = "false", security = 
"insecure:dev")
+    private boolean allowOperationHeader;
+
     @UriParam(label = "advanced",
               description = "An existing WorkloadApiClient to use. When set, 
the component does not"
                             + " create or close its own client and 
spiffeSocketPath is ignored.")
@@ -77,6 +80,21 @@ public class SpiffeConfiguration implements Cloneable {
         this.audience = audience;
     }
 
+    public boolean isAllowOperationHeader() {
+        return allowOperationHeader;
+    }
+
+    /**
+     * Whether the {@code CamelSpiffeOperation} header may override the 
configured operation.
+     * <p/>
+     * Disabled by default: the operation decides whether this endpoint 
<em>validates</em> a token or <em>mints</em>
+     * one, so a message that can set it can turn a validator into an endpoint 
that hands out this workload's own
+     * JWT-SVID. Enable it only on routes whose input is trusted.
+     */
+    public void setAllowOperationHeader(boolean allowOperationHeader) {
+        this.allowOperationHeader = allowOperationHeader;
+    }
+
     /**
      * An already-configured {@link WorkloadApiClient} to use instead of 
letting the endpoint create one.
      */
diff --git 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConstants.java
 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConstants.java
index 9091a159efef..349e30523515 100644
--- 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConstants.java
+++ 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeConstants.java
@@ -21,12 +21,17 @@ import org.apache.camel.spi.Metadata;
 public final class SpiffeConstants {
     private static final String HEADER_PREFIX = "CamelSpiffe";
 
-    @Metadata(label = "producer", description = "Overrides the operation to be 
used by the producer.",
+    @Metadata(label = "producer",
+              description = "Overrides the operation to be used by the 
producer. Ignored unless the endpoint sets"
+                            + " allowOperationHeader=true, because the 
operation decides whether the endpoint"
+                            + " validates a token or mints one.",
               javaType = "org.apache.camel.component.spiffe.SpiffeOperation or 
String")
     public static final String OPERATION = HEADER_PREFIX + "Operation";
 
     @Metadata(label = "producer",
-              description = "The comma-separated audience(s) for the 
fetchJwtSvid and validateJwtSvid operations.",
+              description = "The comma-separated audience(s) for the 
fetchJwtSvid operation. Ignored by"
+                            + " validateJwtSvid, which always validates 
against the configured audience: there the"
+                            + " audience is the check that binds the token to 
this workload, not a parameter.",
               javaType = "String")
     public static final String AUDIENCE = HEADER_PREFIX + "Audience";
 
diff --git 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeProducer.java
 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeProducer.java
index f66c2f16df06..ec38b420261f 100644
--- 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeProducer.java
+++ 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeProducer.java
@@ -75,7 +75,10 @@ public class SpiffeProducer extends DefaultProducer {
             throw new IllegalArgumentException(
                     "A JWT-SVID token is required for validateJwtSvid (set the 
CamelSpiffeToken header or the body)");
         }
-        String[] audiences = resolveAudiences(exchange);
+        // the audience is the check here, not a parameter: it is what binds 
the token to THIS workload, so it
+        // comes from the configuration only. Honouring CamelSpiffeAudience 
would let a caller validate a token
+        // minted for someone else against an audience of their choosing.
+        String[] audiences = resolveConfiguredAudiences();
         JwtSvid svid = client.validateJwtSvid(token, audiences[0]);
         Message message = getMessageForResponse(exchange);
         message.setBody(svid);
@@ -83,27 +86,44 @@ public class SpiffeProducer extends DefaultProducer {
     }
 
     private SpiffeOperation determineOperation(Exchange exchange) {
+        SpiffeOperation configured = 
getEndpoint().getConfiguration().getOperation();
+        if (!getEndpoint().getConfiguration().isAllowOperationHeader()) {
+            return configured;
+        }
         SpiffeOperation operation
                 = exchange.getIn().getHeader(SpiffeConstants.OPERATION, 
SpiffeOperation.class);
-        return operation != null ? operation : 
getEndpoint().getConfiguration().getOperation();
+        return operation != null ? operation : configured;
     }
 
+    /**
+     * Audience for a fetch: a genuine per-message parameter, so the header 
may override the configuration.
+     */
     private String[] resolveAudiences(Exchange exchange) {
         String audience = exchange.getIn().getHeader(SpiffeConstants.AUDIENCE, 
String.class);
         if (ObjectHelper.isEmpty(audience)) {
             audience = getEndpoint().getConfiguration().getAudience();
         }
+        return splitAudiences(audience, "set the audience option or the 
CamelSpiffeAudience header");
+    }
+
+    /**
+     * Audience for a validation: taken from the configuration only, never 
from the message.
+     */
+    private String[] resolveConfiguredAudiences() {
+        // deliberately does not mention the header: it is ignored for 
validation
+        return splitAudiences(getEndpoint().getConfiguration().getAudience(), 
"set the audience option");
+    }
+
+    private String[] splitAudiences(String audience, String how) {
         if (ObjectHelper.isEmpty(audience)) {
-            throw new IllegalArgumentException(
-                    "At least one audience is required (set the audience 
option or the CamelSpiffeAudience header)");
+            throw new IllegalArgumentException("At least one audience is 
required (" + how + ")");
         }
         String[] parts = Arrays.stream(audience.split(","))
                 .map(String::trim)
                 .filter(s -> !s.isEmpty())
                 .toArray(String[]::new);
         if (parts.length == 0) {
-            throw new IllegalArgumentException(
-                    "At least one non-blank audience is required (set the 
audience option or the CamelSpiffeAudience header)");
+            throw new IllegalArgumentException("At least one non-blank 
audience is required (" + how + ")");
         }
         return parts;
     }
diff --git 
a/components/camel-spiffe/src/test/java/org/apache/camel/component/spiffe/SpiffeHeaderOverrideTest.java
 
b/components/camel-spiffe/src/test/java/org/apache/camel/component/spiffe/SpiffeHeaderOverrideTest.java
new file mode 100644
index 000000000000..51727c805923
--- /dev/null
+++ 
b/components/camel-spiffe/src/test/java/org/apache/camel/component/spiffe/SpiffeHeaderOverrideTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.spiffe;
+
+import io.spiffe.spiffeid.SpiffeId;
+import io.spiffe.svid.jwtsvid.JwtSvid;
+import io.spiffe.workloadapi.WorkloadApiClient;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Covers which message headers may steer the producer.
+ * <p/>
+ * The operation decides whether the endpoint validates a token or mints one, 
and for a validation the audience is the
+ * check that binds the token to this workload - neither may be chosen by the 
message unless the route opts in.
+ */
+class SpiffeHeaderOverrideTest extends CamelTestSupport {
+
+    private static final String CONFIGURED_AUDIENCE = 
"spiffe://example.org/my-service";
+    private static final String OTHER_AUDIENCE = 
"spiffe://example.org/other-service";
+
+    @BindToRegistry("client")
+    private final WorkloadApiClient client = mock(WorkloadApiClient.class);
+
+    private static JwtSvid svid() {
+        JwtSvid svid = mock(JwtSvid.class);
+        
when(svid.getSpiffeId()).thenReturn(SpiffeId.parse("spiffe://example.org/workload"));
+        when(svid.getToken()).thenReturn("minted-token");
+        return svid;
+    }
+
+    private String validator() {
+        return 
"spiffe:v?workloadApiClient=#client&operation=validateJwtSvid&audience=" + 
CONFIGURED_AUDIENCE;
+    }
+
+    @Test
+    void validationIgnoresTheAudienceHeader() throws Exception {
+        JwtSvid stub = svid();
+        when(client.validateJwtSvid(anyString(), 
anyString())).thenReturn(stub);
+
+        Exchange out = template.request(validator(), e -> {
+            e.getIn().setHeader(SpiffeConstants.TOKEN, "a-token");
+            e.getIn().setHeader(SpiffeConstants.AUDIENCE, OTHER_AUDIENCE);
+        });
+
+        assertThat(out.getException()).isNull();
+        ArgumentCaptor<String> audience = 
ArgumentCaptor.forClass(String.class);
+        verify(client).validateJwtSvid(anyString(), audience.capture());
+        assertThat(audience.getValue()).isEqualTo(CONFIGURED_AUDIENCE);
+    }
+
+    @Test
+    void aFetchStillHonoursTheAudienceHeader() throws Exception {
+        JwtSvid stub = svid();
+        when(client.fetchJwtSvid(anyString())).thenReturn(stub);
+
+        
template.request("spiffe:v?workloadApiClient=#client&operation=fetchJwtSvid&audience="
 + CONFIGURED_AUDIENCE,
+                e -> e.getIn().setHeader(SpiffeConstants.AUDIENCE, 
OTHER_AUDIENCE));
+
+        // minting a token for a named audience is a parameter, not a check
+        verify(client).fetchJwtSvid(OTHER_AUDIENCE);
+    }
+
+    @Test
+    void theOperationHeaderCannotTurnAValidatorIntoAMinter() throws Exception {
+        Exchange out = template.request(validator(),
+                e -> e.getIn().setHeader(SpiffeConstants.OPERATION, 
"fetchJwtSvid"));
+
+        // the endpoint stays a validator: no token is minted, and the missing 
token is what fails
+        verify(client, never()).fetchJwtSvid(anyString());
+        
assertThat(out.getException()).isInstanceOf(IllegalArgumentException.class);
+        assertThat(out.getException().getMessage()).contains("JWT-SVID token 
is required");
+    }
+
+    @Test
+    void theOperationHeaderWorksWhenTheRouteOptsIn() throws Exception {
+        JwtSvid stub = svid();
+        when(client.fetchJwtSvid(anyString())).thenReturn(stub);
+
+        Exchange out = template.request(validator() + 
"&allowOperationHeader=true",
+                e -> e.getIn().setHeader(SpiffeConstants.OPERATION, 
"fetchJwtSvid"));
+
+        assertThat(out.getException()).isNull();
+        assertThat(out.getMessage().getBody()).isEqualTo("minted-token");
+        verify(client).fetchJwtSvid(CONFIGURED_AUDIENCE);
+    }
+}
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java 
b/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
index ea18612da6ec..0e7e42151dba 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
@@ -63,6 +63,7 @@ public final class SecurityUtils {
         map.put("allowfilepathsource", new SecurityOption(INSECURE_DEV, 
"true"));
         map.put("allowjavaserializedobject", new 
SecurityOption(INSECURE_SERIALIZATION, "true"));
         map.put("allowlocalwebhookurls", new SecurityOption(INSECURE_DEV, 
"true"));
+        map.put("allowoperationheader", new SecurityOption(INSECURE_DEV, 
"true"));
         map.put("allowpredicatefrommessage", new SecurityOption(INSECURE_DEV, 
"true"));
         map.put("allowserializedheaders", new 
SecurityOption(INSECURE_SERIALIZATION, "true"));
         map.put("allowurlbody", new SecurityOption(INSECURE_DEV, "true"));
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpiffeComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpiffeComponentBuilderFactory.java
index f5a35a3bd920..adbba0194947 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpiffeComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpiffeComponentBuilderFactory.java
@@ -171,6 +171,27 @@ public interface SpiffeComponentBuilderFactory {
             return this;
         }
     
+        
+        /**
+         * Whether the CamelSpiffeOperation header may override the configured
+         * operation. Disabled by default: the operation decides whether this
+         * endpoint validates a token or mints one, so a message that can set 
it
+         * can turn a validator into an endpoint that hands out this workload's
+         * own JWT-SVID. Enable it only on routes whose input is trusted.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowOperationHeader the value to set
+         * @return the dsl builder
+         */
+        default SpiffeComponentBuilder allowOperationHeader(boolean 
allowOperationHeader) {
+            doSetProperty("allowOperationHeader", allowOperationHeader);
+            return this;
+        }
+    
         /**
          * The address of the SPIFFE Workload API endpoint (for example {code
          * unix:///tmp/agent.sock} or {code tcp://127.0.0.1:8082}). When not
@@ -214,6 +235,7 @@ public interface SpiffeComponentBuilderFactory {
             case "operation": getOrCreateConfiguration((SpiffeComponent) 
component).setOperation((org.apache.camel.component.spiffe.SpiffeOperation) 
value); return true;
             case "autowiredEnabled": ((SpiffeComponent) 
component).setAutowiredEnabled((boolean) value); return true;
             case "workloadApiClient": 
getOrCreateConfiguration((SpiffeComponent) 
component).setWorkloadApiClient((io.spiffe.workloadapi.WorkloadApiClient) 
value); return true;
+            case "allowOperationHeader": 
getOrCreateConfiguration((SpiffeComponent) 
component).setAllowOperationHeader((boolean) value); return true;
             case "spiffeSocketPath": 
getOrCreateConfiguration((SpiffeComponent) 
component).setSpiffeSocketPath((java.lang.String) value); return true;
             default: return false;
             }
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpiffeEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpiffeEndpointBuilderFactory.java
index b24adceb3542..3e5c862c05e7 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpiffeEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SpiffeEndpointBuilderFactory.java
@@ -96,6 +96,44 @@ public interface SpiffeEndpointBuilderFactory {
             doSetProperty("operation", operation);
             return this;
         }
+        /**
+         * Whether the CamelSpiffeOperation header may override the configured
+         * operation. Disabled by default: the operation decides whether this
+         * endpoint validates a token or mints one, so a message that can set 
it
+         * can turn a validator into an endpoint that hands out this workload's
+         * own JWT-SVID. Enable it only on routes whose input is trusted.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowOperationHeader the value to set
+         * @return the dsl builder
+         */
+        default SpiffeEndpointBuilder allowOperationHeader(boolean 
allowOperationHeader) {
+            doSetProperty("allowOperationHeader", allowOperationHeader);
+            return this;
+        }
+        /**
+         * Whether the CamelSpiffeOperation header may override the configured
+         * operation. Disabled by default: the operation decides whether this
+         * endpoint validates a token or mints one, so a message that can set 
it
+         * can turn a validator into an endpoint that hands out this workload's
+         * own JWT-SVID. Enable it only on routes whose input is trusted.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: security
+         * 
+         * @param allowOperationHeader the value to set
+         * @return the dsl builder
+         */
+        default SpiffeEndpointBuilder allowOperationHeader(String 
allowOperationHeader) {
+            doSetProperty("allowOperationHeader", allowOperationHeader);
+            return this;
+        }
         /**
          * The address of the SPIFFE Workload API endpoint (for example {code
          * unix:///tmp/agent.sock} or {code tcp://127.0.0.1:8082}). When not
@@ -274,7 +312,9 @@ public interface SpiffeEndpointBuilderFactory {
         public static final SpiffeHeaderNameBuilder INSTANCE = new 
SpiffeHeaderNameBuilder();
 
         /**
-         * Overrides the operation to be used by the producer.
+         * Overrides the operation to be used by the producer. Ignored unless
+         * the endpoint sets allowOperationHeader=true, because the operation
+         * decides whether the endpoint validates a token or mints one.
          * 
          * The option is a: {@code
          * org.apache.camel.component.spiffe.SpiffeOperation or String} type.
@@ -287,8 +327,10 @@ public interface SpiffeEndpointBuilderFactory {
             return "CamelSpiffeOperation";
         }
         /**
-         * The comma-separated audience(s) for the fetchJwtSvid and
-         * validateJwtSvid operations.
+         * The comma-separated audience(s) for the fetchJwtSvid operation.
+         * Ignored by validateJwtSvid, which always validates against the
+         * configured audience: there the audience is the check that binds the
+         * token to this workload, not a parameter.
          * 
          * The option is a: {@code String} type.
          * 

Reply via email to