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 7d6839a80af9 CAMEL-25026: camel-package-maven-plugin - propagate
@Metadata security attributes for model, dataformat and language options
(#26900)
7d6839a80af9 is described below
commit 7d6839a80af95e69563fb5f1b11998ced82f6b3b
Author: Andrea Cosentino <[email protected]>
AuthorDate: Sat Sep 26 14:59:05 2026 +0200
CAMEL-25026: camel-package-maven-plugin - propagate @Metadata security
attributes for model, dataformat and language options (#26900)
SchemaGeneratorMojo.createOption never read the security, secret and
insecureValue attributes off @Metadata, so every model, dataformat and
language option lost them. Only component options kept them, because
EndpointSchemaGeneratorMojo resolves them separately.
The loss is silent. An option that declares security = "insecure:ssl" or
secret = true simply does not reach the generated SecurityUtils and
SensitiveUtils tables, so it gets no prod-profile enforcement, no
jbang security-scan coverage and no value masking - with nothing in the
build to signal it.
Add applySecurityMetadata and call it at the four field-driven
createOption sites (processAttribute, processValue, processElement,
processElements) plus the exchange-property branch, which had its own
inline copy. The resolution mirrors EndpointSchemaGeneratorMojo:
secret = true and security = "secret" each imply the other. It is kept
out of createOption itself because most of its callers build synthetic
options (routes, autoStartup, ...) that have no annotation to read.
PackageDataFormatMojo copied only isSecret when folding a model option
into the dataformat JSON, so it dropped the other two again on the way
out. It now copies all three. PackageLanguageMojo already did.
Two data formats are affected today: xmlSecurity (passPhrase,
passPhraseByte, keyPassword now secret) and avro (serializablePackages
now insecure:serialization). No option changed its default or meaning.
The only user-visible effects are that passPhraseByte is now masked
wherever Camel sanitizes values, and that the YAML DSL schema marks
passPhrase and keyPassword as "format": "password".
Signed-off-by: Andrea Cosentino <[email protected]>
Co-authored-by: Claude Opus 5 <[email protected]>
---
.../org/apache/camel/catalog/dataformats/avro.json | 2 +-
.../camel/catalog/dataformats/xmlSecurity.json | 6 +-
.../apache/camel/catalog/main/sensitive-keys.json | 1 +
.../org/apache/camel/catalog/models/avro.json | 2 +-
.../apache/camel/catalog/models/xmlSecurity.json | 6 +-
.../org/apache/camel/dataformat/avro/avro.json | 2 +-
.../camel/dataformat/xmlsecurity/xmlSecurity.json | 6 +-
.../org/apache/camel/model/dataformat/avro.json | 2 +-
.../apache/camel/model/dataformat/xmlSecurity.json | 6 +-
.../java/org/apache/camel/util/SensitiveUtils.java | 2 +
.../ROOT/pages/camel-4x-upgrade-guide-4_23.adoc | 14 +++
.../dsl/yaml/deserializers/ModelDeserializers.java | 4 +-
.../resources/schema/camelYamlDsl-canonical.json | 6 +-
.../generated/resources/schema/camelYamlDsl.json | 6 +-
.../maven/packaging/PackageDataFormatMojo.java | 2 +
.../camel/maven/packaging/SchemaGeneratorMojo.java | 38 +++++--
.../SchemaGeneratorMojoSecurityMetadataTest.java | 122 +++++++++++++++++++++
17 files changed, 198 insertions(+), 29 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/avro.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/avro.json
index 63a7e01f75db..741ddee8defd 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/avro.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/avro.json
@@ -18,6 +18,6 @@
"properties": {
"id": { "index": 0, "kind": "attribute", "displayName": "Id", "group":
"common", "required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description": "The
id of this node" },
"instanceClassName": { "index": 1, "kind": "attribute", "displayName":
"Instance Class Name", "group": "common", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "Class name to use for marshal and
unmarshalling." },
- "serializablePackages": { "index": 2, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Comma-separated list of
additional packages that contain trusted Avro model classes. Avro 1.12
validates classes resolved from schemas; Camel automatically trusts packages
derived from the configured sche [...]
+ "serializablePackages": { "index": 2, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:serialization",
"description": "Comma-separated list of additional packages that contain
trusted Avro model classes. Avro 1.12 validates classes resolved from schemas;
Camel automatically trusts pac [...]
}
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/xmlSecurity.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/xmlSecurity.json
index 6ab9baf91e2e..518be305a0fc 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/xmlSecurity.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/xmlSecurity.json
@@ -18,14 +18,14 @@
"properties": {
"id": { "index": 0, "kind": "attribute", "displayName": "Id", "group":
"common", "required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description": "The
id of this node" },
"xmlCipherAlgorithm": { "index": 1, "kind": "attribute", "displayName":
"Xml Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "TRIPLEDES", "AES_128",
"AES_128_GCM", "AES_192", "AES_192_GCM", "AES_256", "AES_256_GCM", "SEED_128",
"CAMELLIA_128", "CAMELLIA_192", "CAMELLIA_256" ], "deprecated": false,
"autowired": false, "secret": false, "defaultValue": "AES_256_GCM",
"description": "The cipher algorithm to be used for en [...]
- "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "A String used as passPhrase to encrypt\/decrypt content." },
- "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": false, "description": "A byte used as passPhrase to
encrypt\/decrypt content." },
+ "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "A String used as passPhrase to
encrypt\/decrypt content." },
+ "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "description": "A byte used as
passPhrase to encrypt\/decrypt content." },
"secureTag": { "index": 4, "kind": "attribute", "displayName": "Secure
Tag", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The XPath reference to the XML Element selected for
encryption\/decryption. If no tag is specified, the entire payload is
encrypted\/decrypted." },
"secureTagContents": { "index": 5, "kind": "attribute", "displayName":
"Secure Tag Contents", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "A boolean value to
specify whether the XML Element is to be encrypted or the contents of the XML
Element. false = Element Level, true = Element Content Level." },
"keyCipherAlgorithm": { "index": 6, "kind": "attribute", "displayName":
"Key Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "RSA_v1dot5", "RSA_OAEP",
"RSA_OAEP_11" ], "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "RSA_OAEP", "description": "The cipher algorithm to be used for
encryption\/decryption of the asymmetric key." },
"recipientKeyAlias": { "index": 7, "kind": "attribute", "displayName":
"Recipient Key Alias", "group": "common", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "The key alias to be used when retrieving the
recipient's public or private key from a KeyStore when performing asymmetric
key encryption or decryption." },
"keyOrTrustStoreParameters": { "index": 8, "kind": "attribute",
"displayName": "Key Or Trust Store Parameters", "group": "common", "required":
false, "type": "object", "javaType":
"org.apache.camel.support.jsse.KeyStoreParameters", "deprecated": false,
"autowired": false, "secret": false, "description": "Refers to a KeyStore
instance to lookup in the registry, which is used for configuration options for
creating and loading a KeyStore instance that represents the sender's
trustStore [...]
- "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The password to be used for retrieving the private key from the
KeyStore. This key is used for asymmetric decryption." },
+ "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "The password to be used for retrieving
the private key from the KeyStore. This key is used for asymmetric decryption."
},
"digestAlgorithm": { "index": 10, "kind": "attribute", "displayName":
"Digest Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "SHA1", "SHA256", "SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"SHA1", "description": "The digest algorithm to use with the RSA OAEP
algorithm." },
"mgfAlgorithm": { "index": 11, "kind": "attribute", "displayName": "Mgf
Algorithm", "group": "common", "required": false, "type": "enum", "javaType":
"java.lang.String", "enum": [ "MGF1_SHA1", "MGF1_SHA256", "MGF1_SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"MGF1_SHA1", "description": "The MGF Algorithm to use with the RSA OAEP
algorithm." },
"addKeyValueForEncryptedKey": { "index": 12, "kind": "attribute",
"displayName": "Add Key Value For Encrypted Key", "group": "common",
"required": false, "type": "boolean", "javaType": "java.lang.Boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Whether to add the public key used to encrypt the session key
as a KeyValue in the EncryptedKey structure or not." },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
index 157a6d605381..f34b628431b6 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
@@ -52,6 +52,7 @@
"oauthtokenurl",
"p12filename",
"passphrase",
+ "passphrasebyte",
"password",
"personalaccesstoken",
"postmanapikey",
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/avro.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/avro.json
index 3c008806e3ba..8b514358e0c2 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/avro.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/avro.json
@@ -34,6 +34,6 @@
"contentTypeHeader": { "index": 18, "kind": "attribute", "displayName":
"Content Type Header", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": true, "description": "Whether the data format
should set the Content-Type header with the type from the data format. For
example application\/xml for data formats marshalling to XML, or
application\/json for data formats marshall [...]
"schemaResolver": { "index": 19, "kind": "attribute", "displayName":
"Schema Resolver", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Optional schema resolver
used to lookup schemas for the data in transit." },
"autoDiscoverSchemaResolver": { "index": 20, "kind": "attribute",
"displayName": "Auto Discover Schema Resolver", "group": "advanced", "label":
"advanced", "required": false, "type": "boolean", "javaType":
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": true, "description": "When not disabled, the SchemaResolver
will be looked up into the registry." },
- "serializablePackages": { "index": 21, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Comma-separated list of
additional packages that contain trusted Avro model classes. Avro 1.12
validates classes resolved from schemas; Camel automatically trusts packages
derived from the configured sch [...]
+ "serializablePackages": { "index": 21, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:serialization",
"description": "Comma-separated list of additional packages that contain
trusted Avro model classes. Avro 1.12 validates classes resolved from schemas;
Camel automatically trusts pa [...]
}
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xmlSecurity.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xmlSecurity.json
index 1a4b815308f1..cc06cf3a4dd4 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xmlSecurity.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/xmlSecurity.json
@@ -15,14 +15,14 @@
"properties": {
"id": { "index": 0, "kind": "attribute", "displayName": "Id", "group":
"common", "required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description": "The
id of this node" },
"xmlCipherAlgorithm": { "index": 1, "kind": "attribute", "displayName":
"Xml Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "TRIPLEDES", "AES_128",
"AES_128_GCM", "AES_192", "AES_192_GCM", "AES_256", "AES_256_GCM", "SEED_128",
"CAMELLIA_128", "CAMELLIA_192", "CAMELLIA_256" ], "deprecated": false,
"autowired": false, "secret": false, "defaultValue": "AES_256_GCM",
"description": "The cipher algorithm to be used for en [...]
- "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "A String used as passPhrase to encrypt\/decrypt content." },
- "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": false, "description": "A byte used as passPhrase to
encrypt\/decrypt content." },
+ "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "A String used as passPhrase to
encrypt\/decrypt content." },
+ "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "description": "A byte used as
passPhrase to encrypt\/decrypt content." },
"secureTag": { "index": 4, "kind": "attribute", "displayName": "Secure
Tag", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The XPath reference to the XML Element selected for
encryption\/decryption. If no tag is specified, the entire payload is
encrypted\/decrypted." },
"secureTagContents": { "index": 5, "kind": "attribute", "displayName":
"Secure Tag Contents", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "A boolean value to
specify whether the XML Element is to be encrypted or the contents of the XML
Element. false = Element Level, true = Element Content Level." },
"keyCipherAlgorithm": { "index": 6, "kind": "attribute", "displayName":
"Key Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "RSA_v1dot5", "RSA_OAEP",
"RSA_OAEP_11" ], "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "RSA_OAEP", "description": "The cipher algorithm to be used for
encryption\/decryption of the asymmetric key." },
"recipientKeyAlias": { "index": 7, "kind": "attribute", "displayName":
"Recipient Key Alias", "group": "common", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "The key alias to be used when retrieving the
recipient's public or private key from a KeyStore when performing asymmetric
key encryption or decryption." },
"keyOrTrustStoreParameters": { "index": 8, "kind": "attribute",
"displayName": "Key Or Trust Store Parameters", "group": "common", "required":
false, "type": "object", "javaType":
"org.apache.camel.support.jsse.KeyStoreParameters", "deprecated": false,
"autowired": false, "secret": false, "description": "Refers to a KeyStore
instance to lookup in the registry, which is used for configuration options for
creating and loading a KeyStore instance that represents the sender's
trustStore [...]
- "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The password to be used for retrieving the private key from the
KeyStore. This key is used for asymmetric decryption." },
+ "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "The password to be used for retrieving
the private key from the KeyStore. This key is used for asymmetric decryption."
},
"digestAlgorithm": { "index": 10, "kind": "attribute", "displayName":
"Digest Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "SHA1", "SHA256", "SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"SHA1", "description": "The digest algorithm to use with the RSA OAEP
algorithm." },
"mgfAlgorithm": { "index": 11, "kind": "attribute", "displayName": "Mgf
Algorithm", "group": "common", "required": false, "type": "enum", "javaType":
"java.lang.String", "enum": [ "MGF1_SHA1", "MGF1_SHA256", "MGF1_SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"MGF1_SHA1", "description": "The MGF Algorithm to use with the RSA OAEP
algorithm." },
"addKeyValueForEncryptedKey": { "index": 12, "kind": "attribute",
"displayName": "Add Key Value For Encrypted Key", "group": "common",
"required": false, "type": "boolean", "javaType": "java.lang.Boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Whether to add the public key used to encrypt the session key
as a KeyValue in the EncryptedKey structure or not." },
diff --git
a/components/camel-avro/src/generated/resources/META-INF/org/apache/camel/dataformat/avro/avro.json
b/components/camel-avro/src/generated/resources/META-INF/org/apache/camel/dataformat/avro/avro.json
index 63a7e01f75db..741ddee8defd 100644
---
a/components/camel-avro/src/generated/resources/META-INF/org/apache/camel/dataformat/avro/avro.json
+++
b/components/camel-avro/src/generated/resources/META-INF/org/apache/camel/dataformat/avro/avro.json
@@ -18,6 +18,6 @@
"properties": {
"id": { "index": 0, "kind": "attribute", "displayName": "Id", "group":
"common", "required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description": "The
id of this node" },
"instanceClassName": { "index": 1, "kind": "attribute", "displayName":
"Instance Class Name", "group": "common", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "Class name to use for marshal and
unmarshalling." },
- "serializablePackages": { "index": 2, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Comma-separated list of
additional packages that contain trusted Avro model classes. Avro 1.12
validates classes resolved from schemas; Camel automatically trusts packages
derived from the configured sche [...]
+ "serializablePackages": { "index": 2, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:serialization",
"description": "Comma-separated list of additional packages that contain
trusted Avro model classes. Avro 1.12 validates classes resolved from schemas;
Camel automatically trusts pac [...]
}
}
diff --git
a/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/dataformat/xmlsecurity/xmlSecurity.json
b/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/dataformat/xmlsecurity/xmlSecurity.json
index 6ab9baf91e2e..518be305a0fc 100644
---
a/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/dataformat/xmlsecurity/xmlSecurity.json
+++
b/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/dataformat/xmlsecurity/xmlSecurity.json
@@ -18,14 +18,14 @@
"properties": {
"id": { "index": 0, "kind": "attribute", "displayName": "Id", "group":
"common", "required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description": "The
id of this node" },
"xmlCipherAlgorithm": { "index": 1, "kind": "attribute", "displayName":
"Xml Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "TRIPLEDES", "AES_128",
"AES_128_GCM", "AES_192", "AES_192_GCM", "AES_256", "AES_256_GCM", "SEED_128",
"CAMELLIA_128", "CAMELLIA_192", "CAMELLIA_256" ], "deprecated": false,
"autowired": false, "secret": false, "defaultValue": "AES_256_GCM",
"description": "The cipher algorithm to be used for en [...]
- "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "A String used as passPhrase to encrypt\/decrypt content." },
- "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": false, "description": "A byte used as passPhrase to
encrypt\/decrypt content." },
+ "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "A String used as passPhrase to
encrypt\/decrypt content." },
+ "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "description": "A byte used as
passPhrase to encrypt\/decrypt content." },
"secureTag": { "index": 4, "kind": "attribute", "displayName": "Secure
Tag", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The XPath reference to the XML Element selected for
encryption\/decryption. If no tag is specified, the entire payload is
encrypted\/decrypted." },
"secureTagContents": { "index": 5, "kind": "attribute", "displayName":
"Secure Tag Contents", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "A boolean value to
specify whether the XML Element is to be encrypted or the contents of the XML
Element. false = Element Level, true = Element Content Level." },
"keyCipherAlgorithm": { "index": 6, "kind": "attribute", "displayName":
"Key Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "RSA_v1dot5", "RSA_OAEP",
"RSA_OAEP_11" ], "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "RSA_OAEP", "description": "The cipher algorithm to be used for
encryption\/decryption of the asymmetric key." },
"recipientKeyAlias": { "index": 7, "kind": "attribute", "displayName":
"Recipient Key Alias", "group": "common", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "The key alias to be used when retrieving the
recipient's public or private key from a KeyStore when performing asymmetric
key encryption or decryption." },
"keyOrTrustStoreParameters": { "index": 8, "kind": "attribute",
"displayName": "Key Or Trust Store Parameters", "group": "common", "required":
false, "type": "object", "javaType":
"org.apache.camel.support.jsse.KeyStoreParameters", "deprecated": false,
"autowired": false, "secret": false, "description": "Refers to a KeyStore
instance to lookup in the registry, which is used for configuration options for
creating and loading a KeyStore instance that represents the sender's
trustStore [...]
- "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The password to be used for retrieving the private key from the
KeyStore. This key is used for asymmetric decryption." },
+ "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "The password to be used for retrieving
the private key from the KeyStore. This key is used for asymmetric decryption."
},
"digestAlgorithm": { "index": 10, "kind": "attribute", "displayName":
"Digest Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "SHA1", "SHA256", "SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"SHA1", "description": "The digest algorithm to use with the RSA OAEP
algorithm." },
"mgfAlgorithm": { "index": 11, "kind": "attribute", "displayName": "Mgf
Algorithm", "group": "common", "required": false, "type": "enum", "javaType":
"java.lang.String", "enum": [ "MGF1_SHA1", "MGF1_SHA256", "MGF1_SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"MGF1_SHA1", "description": "The MGF Algorithm to use with the RSA OAEP
algorithm." },
"addKeyValueForEncryptedKey": { "index": 12, "kind": "attribute",
"displayName": "Add Key Value For Encrypted Key", "group": "common",
"required": false, "type": "boolean", "javaType": "java.lang.Boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Whether to add the public key used to encrypt the session key
as a KeyValue in the EncryptedKey structure or not." },
diff --git
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/avro.json
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/avro.json
index 3c008806e3ba..8b514358e0c2 100644
---
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/avro.json
+++
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/avro.json
@@ -34,6 +34,6 @@
"contentTypeHeader": { "index": 18, "kind": "attribute", "displayName":
"Content Type Header", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": true, "description": "Whether the data format
should set the Content-Type header with the type from the data format. For
example application\/xml for data formats marshalling to XML, or
application\/json for data formats marshall [...]
"schemaResolver": { "index": 19, "kind": "attribute", "displayName":
"Schema Resolver", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Optional schema resolver
used to lookup schemas for the data in transit." },
"autoDiscoverSchemaResolver": { "index": 20, "kind": "attribute",
"displayName": "Auto Discover Schema Resolver", "group": "advanced", "label":
"advanced", "required": false, "type": "boolean", "javaType":
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": true, "description": "When not disabled, the SchemaResolver
will be looked up into the registry." },
- "serializablePackages": { "index": 21, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Comma-separated list of
additional packages that contain trusted Avro model classes. Avro 1.12
validates classes resolved from schemas; Camel automatically trusts packages
derived from the configured sch [...]
+ "serializablePackages": { "index": 21, "kind": "attribute", "displayName":
"Serializable Packages", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "security": "insecure:serialization",
"description": "Comma-separated list of additional packages that contain
trusted Avro model classes. Avro 1.12 validates classes resolved from schemas;
Camel automatically trusts pa [...]
}
}
diff --git
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/xmlSecurity.json
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/xmlSecurity.json
index 1a4b815308f1..cc06cf3a4dd4 100644
---
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/xmlSecurity.json
+++
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/xmlSecurity.json
@@ -15,14 +15,14 @@
"properties": {
"id": { "index": 0, "kind": "attribute", "displayName": "Id", "group":
"common", "required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description": "The
id of this node" },
"xmlCipherAlgorithm": { "index": 1, "kind": "attribute", "displayName":
"Xml Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "TRIPLEDES", "AES_128",
"AES_128_GCM", "AES_192", "AES_192_GCM", "AES_256", "AES_256_GCM", "SEED_128",
"CAMELLIA_128", "CAMELLIA_192", "CAMELLIA_256" ], "deprecated": false,
"autowired": false, "secret": false, "defaultValue": "AES_256_GCM",
"description": "The cipher algorithm to be used for en [...]
- "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "A String used as passPhrase to encrypt\/decrypt content." },
- "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": false, "description": "A byte used as passPhrase to
encrypt\/decrypt content." },
+ "passPhrase": { "index": 2, "kind": "attribute", "displayName": "Pass
Phrase", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "A String used as passPhrase to
encrypt\/decrypt content." },
+ "passPhraseByte": { "index": 3, "kind": "attribute", "displayName": "Pass
Phrase Byte", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "byte[]", "deprecated": false, "autowired":
false, "secret": true, "security": "secret", "description": "A byte used as
passPhrase to encrypt\/decrypt content." },
"secureTag": { "index": 4, "kind": "attribute", "displayName": "Secure
Tag", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The XPath reference to the XML Element selected for
encryption\/decryption. If no tag is specified, the entire payload is
encrypted\/decrypted." },
"secureTagContents": { "index": 5, "kind": "attribute", "displayName":
"Secure Tag Contents", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "A boolean value to
specify whether the XML Element is to be encrypted or the contents of the XML
Element. false = Element Level, true = Element Content Level." },
"keyCipherAlgorithm": { "index": 6, "kind": "attribute", "displayName":
"Key Cipher Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "RSA_v1dot5", "RSA_OAEP",
"RSA_OAEP_11" ], "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "RSA_OAEP", "description": "The cipher algorithm to be used for
encryption\/decryption of the asymmetric key." },
"recipientKeyAlias": { "index": 7, "kind": "attribute", "displayName":
"Recipient Key Alias", "group": "common", "required": false, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "The key alias to be used when retrieving the
recipient's public or private key from a KeyStore when performing asymmetric
key encryption or decryption." },
"keyOrTrustStoreParameters": { "index": 8, "kind": "attribute",
"displayName": "Key Or Trust Store Parameters", "group": "common", "required":
false, "type": "object", "javaType":
"org.apache.camel.support.jsse.KeyStoreParameters", "deprecated": false,
"autowired": false, "secret": false, "description": "Refers to a KeyStore
instance to lookup in the registry, which is used for configuration options for
creating and loading a KeyStore instance that represents the sender's
trustStore [...]
- "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": false,
"description": "The password to be used for retrieving the private key from the
KeyStore. This key is used for asymmetric decryption." },
+ "keyPassword": { "index": 9, "kind": "attribute", "displayName": "Key
Password", "group": "common", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "autowired": false, "secret": true,
"security": "secret", "description": "The password to be used for retrieving
the private key from the KeyStore. This key is used for asymmetric decryption."
},
"digestAlgorithm": { "index": 10, "kind": "attribute", "displayName":
"Digest Algorithm", "group": "common", "required": false, "type": "enum",
"javaType": "java.lang.String", "enum": [ "SHA1", "SHA256", "SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"SHA1", "description": "The digest algorithm to use with the RSA OAEP
algorithm." },
"mgfAlgorithm": { "index": 11, "kind": "attribute", "displayName": "Mgf
Algorithm", "group": "common", "required": false, "type": "enum", "javaType":
"java.lang.String", "enum": [ "MGF1_SHA1", "MGF1_SHA256", "MGF1_SHA512" ],
"deprecated": false, "autowired": false, "secret": false, "defaultValue":
"MGF1_SHA1", "description": "The MGF Algorithm to use with the RSA OAEP
algorithm." },
"addKeyValueForEncryptedKey": { "index": 12, "kind": "attribute",
"displayName": "Add Key Value For Encrypted Key", "group": "common",
"required": false, "type": "boolean", "javaType": "java.lang.Boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Whether to add the public key used to encrypt the session key
as a KeyValue in the EncryptedKey structure or not." },
diff --git
a/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
b/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
index f5a254b3ff6a..27ee2244656f 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
@@ -91,6 +91,7 @@ public final class SensitiveUtils {
"oauthtokenurl",
"p12filename",
"passphrase",
+ "passphrasebyte",
"password",
"personalaccesstoken",
"postmanapikey",
@@ -197,6 +198,7 @@ public final class SensitiveUtils {
+ "|\\Qoauthtokenurl\\E"
+ "|\\Qp12filename\\E"
+ "|\\Qpassphrase\\E"
+ + "|\\Qpassphrasebyte\\E"
+ "|\\Qpassword\\E"
+
"|\\Qpersonalaccesstoken\\E"
+ "|\\Qpostmanapikey\\E"
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index c2d3df2b39d4..4503dbd53743 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -2913,6 +2913,20 @@ producer were never stopped.
With `parallelProcessing`, a recipient whose task had not started yet when the
Recipient List completed is now
skipped instead of being sent to afterwards. As before, recipients that had
already started keep running.
+=== camel-xmlsecurity, camel-avro - data format options now carry their
security metadata
+
+The `security` and `secret` attributes of `@Metadata` were never written to
the generated metadata of data format,
+language and model options, only to that of component options. They are now
generated for all of them.
+
+Two data formats are affected. On `xmlSecurity` the `passPhrase`,
`passPhraseByte` and `keyPassword` options are now
+reported as secret, and on `avro` the `serializablePackages` option is now
reported under the `insecure:serialization`
+category. No option changed its default or its meaning.
+
+This is visible in two places. `passPhraseByte` is now masked as `xxxxxx`
wherever Camel sanitizes values, such as in
+logged endpoint URIs and route dumps; `passPhrase` and `keyPassword` were
already masked because other components
+declare options with the same names. The YAML DSL JSON schema now also marks
`passPhrase` and `keyPassword` with
+`"format": "password"`, so editors that consume the schema render them as
password fields.
+
== ThrottlingExceptionRoutePolicy
`ThrottlingExceptionRoutePolicy.setKeepOpen(true)` now opens the circuit
immediately and synchronously (the consumer
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index e163c8bca2ca..024263761443 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -21124,10 +21124,10 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "id", type = "string", description =
"The id of this node", displayName = "Id"),
@YamlProperty(name = "keyCipherAlgorithm", type =
"enum:RSA_v1dot5,RSA_OAEP,RSA_OAEP_11", defaultValue = "RSA_OAEP", description
= "The cipher algorithm to be used for encryption/decryption of the asymmetric
key.", displayName = "Key Cipher Algorithm"),
@YamlProperty(name = "keyOrTrustStoreParameters", type =
"string", description = "Refers to a KeyStore instance to lookup in the
registry, which is used for configuration options for creating and loading a
KeyStore instance that represents the sender's trustStore or recipient's
keyStore.", displayName = "Key Or Trust Store Parameters"),
- @YamlProperty(name = "keyPassword", type = "string",
description = "The password to be used for retrieving the private key from the
KeyStore. This key is used for asymmetric decryption.", displayName = "Key
Password"),
+ @YamlProperty(name = "keyPassword", type = "string",
format = "password", description = "The password to be used for retrieving the
private key from the KeyStore. This key is used for asymmetric decryption.",
displayName = "Key Password"),
@YamlProperty(name = "mgfAlgorithm", type =
"enum:MGF1_SHA1,MGF1_SHA256,MGF1_SHA512", defaultValue = "MGF1_SHA1",
description = "The MGF Algorithm to use with the RSA OAEP algorithm.",
displayName = "Mgf Algorithm"),
@YamlProperty(name = "namespace", type = "string",
description = "Refers to a Map of XML Namespaces of prefix to uri mappings.",
displayName = "Namespace"),
- @YamlProperty(name = "passPhrase", type = "string",
description = "A String used as passPhrase to encrypt/decrypt content.",
displayName = "Pass Phrase"),
+ @YamlProperty(name = "passPhrase", type = "string", format
= "password", description = "A String used as passPhrase to encrypt/decrypt
content.", displayName = "Pass Phrase"),
@YamlProperty(name = "passPhraseByte", type = "string",
format = "binary", description = "A byte used as passPhrase to encrypt/decrypt
content.", displayName = "Pass Phrase Byte"),
@YamlProperty(name = "recipientKeyAlias", type = "string",
description = "The key alias to be used when retrieving the recipient's public
or private key from a KeyStore when performing asymmetric key encryption or
decryption.", displayName = "Recipient Key Alias"),
@YamlProperty(name = "secureTag", type = "string",
description = "The XPath reference to the XML Element selected for
encryption/decryption. If no tag is specified, the entire payload is
encrypted/decrypted.", displayName = "Secure Tag"),
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
index 4f6428646a7f..b39d62d36211 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
@@ -9013,7 +9013,8 @@
"keyPassword" : {
"type" : "string",
"title" : "Key Password",
- "description" : "The password to be used for retrieving the
private key from the KeyStore. This key is used for asymmetric decryption."
+ "description" : "The password to be used for retrieving the
private key from the KeyStore. This key is used for asymmetric decryption.",
+ "format" : "password"
},
"mgfAlgorithm" : {
"type" : "string",
@@ -9030,7 +9031,8 @@
"passPhrase" : {
"type" : "string",
"title" : "Pass Phrase",
- "description" : "A String used as passPhrase to encrypt/decrypt
content."
+ "description" : "A String used as passPhrase to encrypt/decrypt
content.",
+ "format" : "password"
},
"passPhraseByte" : {
"type" : "string",
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index 3175cf29db31..dbf079b5f2c4 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -11220,7 +11220,8 @@
"keyPassword" : {
"type" : "string",
"title" : "Key Password",
- "description" : "The password to be used for retrieving the
private key from the KeyStore. This key is used for asymmetric decryption."
+ "description" : "The password to be used for retrieving the
private key from the KeyStore. This key is used for asymmetric decryption.",
+ "format" : "password"
},
"mgfAlgorithm" : {
"type" : "string",
@@ -11237,7 +11238,8 @@
"passPhrase" : {
"type" : "string",
"title" : "Pass Phrase",
- "description" : "A String used as passPhrase to encrypt/decrypt
content."
+ "description" : "A String used as passPhrase to encrypt/decrypt
content.",
+ "format" : "password"
},
"passPhraseByte" : {
"type" : "string",
diff --git
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java
index e556ce530233..a55978d31ebe 100644
---
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java
+++
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java
@@ -359,6 +359,8 @@ public class PackageDataFormatMojo extends
AbstractGeneratorMojo {
option.setDeprecated(opt.isDeprecated());
option.setDeprecationNote(opt.getDeprecationNote());
option.setSecret(opt.isSecret());
+ option.setSecurity(opt.getSecurity());
+ option.setInsecureValue(opt.getInsecureValue());
option.setDefaultValue(opt.getDefaultValue());
option.setDefaultValueNote(opt.getDefaultValueNote());
option.setAsPredicate(opt.isAsPredicate());
diff --git
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
index 3880cabda9ae..cc89bcc453d7 100644
---
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
+++
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
@@ -402,13 +402,7 @@ public class SchemaGeneratorMojo extends
AbstractGeneratorMojo {
if (!metadata.deprecationNote().isEmpty()) {
o.setDeprecationNote(metadata.deprecationNote());
}
- o.setSecret(metadata.secret());
- String sec = metadata.security();
- if (Strings.isNullOrEmpty(sec) && metadata.secret()) {
- sec = "secret";
- }
- o.setSecurity(sec);
- o.setInsecureValue(metadata.insecureValue());
+ applySecurityMetadata(o, metadata);
o.setJavaType(metadata.javaType());
// special if the property is for input (such as
AGGREGATION_COMPLETE_CURRENT_GROUP)
if (labels.startsWith("consumer,")) {
@@ -601,6 +595,7 @@ public class SchemaGeneratorMojo extends
AbstractGeneratorMojo {
EipOptionModel ep = createOption(name, displayName, "attribute",
fieldTypeName,
required, defaultValue, label, docComment, deprecated,
deprecationNote, isEnum, enums,
null, false, isDuration, important);
+ applySecurityMetadata(ep, metadata);
eipOptions.add(ep);
return false;
@@ -658,6 +653,7 @@ public class SchemaGeneratorMojo extends
AbstractGeneratorMojo {
EipOptionModel ep = createOption(name, displayName, "value",
fieldTypeName, required,
defaultValue, label, docComment, deprecated, deprecationNote,
false, null,
null, false, isDuration, important);
+ applySecurityMetadata(ep, metadata);
eipOptions.add(ep);
}
@@ -747,6 +743,7 @@ public class SchemaGeneratorMojo extends
AbstractGeneratorMojo {
EipOptionModel ep = createOption(name, displayName, kind,
fieldTypeName, required, defaultValue, label,
docComment, deprecated, deprecationNote, isEnum, enums,
oneOfTypes, asPredicate, isDuration, important);
+ applySecurityMetadata(ep, metadata);
eipOptions.add(ep);
}
}
@@ -795,6 +792,7 @@ public class SchemaGeneratorMojo extends
AbstractGeneratorMojo {
EipOptionModel ep = createOption(name, displayName, kind,
fieldTypeName, required, defaultValue, label, docComment,
deprecated, deprecationNote, false, null, oneOfTypes,
false, false, important);
+ applySecurityMetadata(ep, metadata);
eipOptions.add(ep);
}
}
@@ -1499,6 +1497,32 @@ public class SchemaGeneratorMojo extends
AbstractGeneratorMojo {
return option;
}
+ /**
+ * Copy the security metadata off {@code @Metadata} onto the option.
+ * <p/>
+ * {@link EndpointSchemaGeneratorMojo} does the equivalent for component
options. Without this the marker is
+ * silently dropped for every model, dataformat and language option, which
in turn keeps them out of the generated
+ * {@code SecurityUtils} and {@code SensitiveUtils} tables - so the option
gets no prod-profile enforcement, no
+ * scanner coverage and no value masking, with nothing in the build to
signal it.
+ * <p/>
+ * The resolution mirrors the component one: {@code secret = true} and
{@code security = "secret"} each imply the
+ * other. This is not folded into {@link #createOption} because most of
its callers build synthetic options (such as
+ * {@code routes} or {@code autoStartup}) that have no annotation to read.
+ */
+ static void applySecurityMetadata(EipOptionModel option, Metadata
metadata) {
+ if (metadata == null) {
+ return;
+ }
+ String security = metadata.security();
+ boolean secret = metadata.secret() || "secret".equals(security);
+ if (Strings.isNullOrEmpty(security) && secret) {
+ security = "secret";
+ }
+ option.setSecret(secret);
+ option.setSecurity(Strings.isNullOrEmpty(security) ? null : security);
+
option.setInsecureValue(Strings.isNullOrEmpty(metadata.insecureValue()) ? null
: metadata.insecureValue());
+ }
+
private boolean hasSuperClass(Class<?> classElement, String
superClassName) {
return loadClass(superClassName).isAssignableFrom(classElement);
}
diff --git
a/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/SchemaGeneratorMojoSecurityMetadataTest.java
b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/SchemaGeneratorMojoSecurityMetadataTest.java
new file mode 100644
index 000000000000..f9eef8d54d87
--- /dev/null
+++
b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/SchemaGeneratorMojoSecurityMetadataTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.maven.packaging;
+
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.tooling.model.EipModel.EipOptionModel;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link SchemaGeneratorMojo} builds the options of every model, dataformat
and language. It used to drop the security
+ * attributes of {@code @Metadata}, which silently kept those options out of
the generated {@code SecurityUtils} and
+ * {@code SensitiveUtils} tables - no prod-profile enforcement, no scanner
coverage, no value masking, and nothing in
+ * the build to signal it.
+ *
+ * @see <a
href="https://issues.apache.org/jira/browse/CAMEL-25026">CAMEL-25026</a>
+ */
+class SchemaGeneratorMojoSecurityMetadataTest {
+
+ @Test
+ void testInsecureCategoryIsCopied() {
+ EipOptionModel option = apply("insecureSerialization");
+
+ assertEquals("insecure:serialization", option.getSecurity());
+ assertFalse(option.isSecret(), "only the secret category implies a
secret value");
+ }
+
+ @Test
+ void testInsecureValueIsCopied() {
+ EipOptionModel option = apply("insecureSsl");
+
+ assertEquals("insecure:ssl", option.getSecurity());
+ assertEquals("true", option.getInsecureValue());
+ }
+
+ @Test
+ void testSecretCategoryImpliesSecret() {
+ EipOptionModel option = apply("secretByCategory");
+
+ assertEquals("secret", option.getSecurity());
+ assertTrue(option.isSecret());
+ }
+
+ @Test
+ void testSecretFlagImpliesSecretCategory() {
+ EipOptionModel option = apply("secretByFlag");
+
+ assertEquals("secret", option.getSecurity());
+ assertTrue(option.isSecret());
+ }
+
+ @Test
+ void testPlainOptionIsLeftAlone() {
+ EipOptionModel option = apply("plain");
+
+ assertNull(option.getSecurity());
+ assertNull(option.getInsecureValue());
+ assertFalse(option.isSecret());
+ }
+
+ @Test
+ void testMissingAnnotationIsLeftAlone() {
+ EipOptionModel option = new EipOptionModel();
+ SchemaGeneratorMojo.applySecurityMetadata(option, null);
+
+ assertNull(option.getSecurity());
+ assertNull(option.getInsecureValue());
+ assertFalse(option.isSecret());
+ }
+
+ private static EipOptionModel apply(String fieldName) {
+ Metadata metadata;
+ try {
+ metadata =
Options.class.getDeclaredField(fieldName).getAnnotation(Metadata.class);
+ } catch (NoSuchFieldException e) {
+ throw new AssertionError(e);
+ }
+ EipOptionModel option = new EipOptionModel();
+ SchemaGeneratorMojo.applySecurityMetadata(option, metadata);
+ return option;
+ }
+
+ /**
+ * Stands in for a model class such as {@code XMLSecurityDataFormat} or
{@code AvroDataFormat}.
+ */
+ @SuppressWarnings("unused")
+ private static final class Options {
+
+ @Metadata(security = "insecure:serialization")
+ private String insecureSerialization;
+
+ @Metadata(security = "insecure:ssl", insecureValue = "true")
+ private String insecureSsl;
+
+ @Metadata(security = "secret")
+ private String secretByCategory;
+
+ @Metadata(secret = true)
+ private String secretByFlag;
+
+ @Metadata(description = "Nothing security related about this one")
+ private String plain;
+ }
+}