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

JiriOndrusek pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus-examples.git

commit 915ac8b848acf1e09f85c871956f6d257fff4535
Author: James Netherton <[email protected]>
AuthorDate: Fri Aug 7 07:11:59 2026 +0100

    Avoid logging secrets and use RAW() property placeholders in the CyberArk 
Vault example
    
    The example logged retrieved secret values at INFO level, which undercuts 
the
    point of a vault integration example. The log statements now report the 
secret
    id and that it resolved, not what it resolved to.
    
    Credentials were interpolated into the endpoint URIs from @ConfigProperty
    fields via String.format. They are now referenced with property placeholders
    wrapped in RAW(), leaving the secret id as the only interpolated value.
    
    RAW() is not cosmetic here. Camel URI decodes query parameter values, so a
    credential containing '+' is silently turned into a space before it reaches
    the component. Conjur API keys are base64 encoded and routinely contain '+':
    
        URISupport.parseQuery("apiKey=3ah+x8/dy3==") -> {apiKey=3ah x8/dy3==}
    
    Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
---
 cyberark-vault/README.adoc                         |  5 ++--
 .../acme/cyberark/vault/CyberarkVaultRoutes.java   | 35 ++++++++--------------
 .../cyberark/vault/CyberarkVaultTestResource.java  |  3 ++
 3 files changed, 18 insertions(+), 25 deletions(-)

diff --git a/cyberark-vault/README.adoc b/cyberark-vault/README.adoc
index 8692f8de..3acb26bd 100644
--- a/cyberark-vault/README.adoc
+++ b/cyberark-vault/README.adoc
@@ -60,8 +60,9 @@ To store a secret, open a new terminal and run:
 curl -X POST http://localhost:8080/cyberark-vault/createSecret -d 
'my-secret-value'
 ----
 
-Following messages will show the resolved secret value. As we run the example 
in Quarkus Dev Mode, you can
-edit the source code and have live updates.
+Following messages will show that the secret resolved successfully. The value 
itself is deliberately not
+logged, since writing secrets to the log defeats the purpose of storing them 
in a vault. As we run the
+example in Quarkus Dev Mode, you can edit the source code and have live 
updates.
 
 TIP: Please refer to the Development mode section of
 
https://camel.apache.org/camel-quarkus/latest/first-steps.html#_development_mode[Camel
 Quarkus User guide] for more details.
diff --git 
a/cyberark-vault/src/main/java/org/acme/cyberark/vault/CyberarkVaultRoutes.java 
b/cyberark-vault/src/main/java/org/acme/cyberark/vault/CyberarkVaultRoutes.java
index a2bef519..05d9a6f1 100644
--- 
a/cyberark-vault/src/main/java/org/acme/cyberark/vault/CyberarkVaultRoutes.java
+++ 
b/cyberark-vault/src/main/java/org/acme/cyberark/vault/CyberarkVaultRoutes.java
@@ -19,41 +19,30 @@ package org.acme.cyberark.vault;
 import jakarta.enterprise.context.ApplicationScoped;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.spi.PropertiesComponent;
-import org.eclipse.microprofile.config.inject.ConfigProperty;
 
 @ApplicationScoped
 public class CyberarkVaultRoutes extends RouteBuilder {
-
-    @ConfigProperty(name = "conjur.url")
-    String url;
-    @ConfigProperty(name = "conjur.account")
-    String account;
-    @ConfigProperty(name = "conjur.writer.username")
-    String writerUsername;
-    @ConfigProperty(name = "conjur.writer.apiKey")
-    String writerApiKey;
-    @ConfigProperty(name = "conjur.reader.username")
-    String readerUsername;
-    @ConfigProperty(name = "conjur.reader.apiKey")
-    String readerApiKey;
+    static final String SECRET_ID = "BotApp/secretVar";
 
     @Override
     public void configure() throws Exception {
 
         from("direct:createSecret")
-                
.toF("cyberark-vault:secret?operation=createSecret&secretId=BotApp/secretVar&url=%s&account=%s&username=%s&apiKey=%s",
-                        url, account, writerUsername, writerApiKey)
-                .log("Secret created/updated");
+                .toF("cyberark-vault:secret?operation=createSecret&secretId=%s"
+                        + "&url={{conjur.url}}&account={{conjur.account}}"
+                        + 
"&username=RAW({{conjur.writer.username}})&apiKey=RAW({{conjur.writer.apiKey}})",
 SECRET_ID)
+                .log("Secret %s created/updated".formatted(SECRET_ID));
 
         from("direct:getSecret")
-                
.toF("cyberark-vault:secret?secretId=BotApp/secretVar&url=%s&account=%s&username=%s&apiKey=%s",
-                        url, account, readerUsername, readerApiKey)
-                .log("Retrieved secret: ${body}");
+                .toF("cyberark-vault:secret?secretId=%s"
+                        + "&url={{conjur.url}}&account={{conjur.account}}"
+                        + 
"&username=RAW({{conjur.reader.username}})&apiKey=RAW({{conjur.reader.apiKey}})",
 SECRET_ID)
+                .log("Secret %s retrieved successfully".formatted(SECRET_ID));
 
         from("direct:propertyPlaceholder")
                 .process(exchange -> {
                     PropertiesComponent component = 
exchange.getContext().getPropertiesComponent();
-                    
component.resolveProperty("cyberark:BotApp/secretVar").ifPresent(value -> {
+                    component.resolveProperty("cyberark:" + 
SECRET_ID).ifPresent(value -> {
                         exchange.getMessage().setBody(value);
                     });
                 });
@@ -63,11 +52,11 @@ public class CyberarkVaultRoutes extends RouteBuilder {
                 .doTry()
                 .process(exchange -> {
                     PropertiesComponent component = 
exchange.getContext().getPropertiesComponent();
-                    
component.resolveProperty("cyberark:BotApp/secretVar").ifPresent(value -> {
+                    component.resolveProperty("cyberark:" + 
SECRET_ID).ifPresent(value -> {
                         exchange.getMessage().setBody(value);
                     });
                 })
-                .log("Property placeholder cyberark:BotApp/secretVar resolved 
to: ${body}")
+                .log("Property placeholder %s resolved 
successfully".formatted(SECRET_ID))
                 .doCatch(Exception.class)
                 .log("No secret stored yet. Create one with: curl -X POST 
http://localhost:8080/cyberark-vault/createSecret -d 'my-secret'")
                 .end();
diff --git 
a/cyberark-vault/src/test/java/org/acme/cyberark/vault/CyberarkVaultTestResource.java
 
b/cyberark-vault/src/test/java/org/acme/cyberark/vault/CyberarkVaultTestResource.java
index 1f1501d0..8ac6603d 100644
--- 
a/cyberark-vault/src/test/java/org/acme/cyberark/vault/CyberarkVaultTestResource.java
+++ 
b/cyberark-vault/src/test/java/org/acme/cyberark/vault/CyberarkVaultTestResource.java
@@ -102,6 +102,9 @@ public class CyberarkVaultTestResource implements 
QuarkusTestResourceLifecycleMa
 
         result.put("camel.vault.cyberark.url", conjurUrl);
         result.put("camel.vault.cyberark.account", CONJUR_ACCOUNT);
+        // The credentials are generated by the Conjur container at runtime, 
so they can only be passed as
+        // plain text here. Camel logs a SECURITY WARNING for each of them at 
startup. That is expected for
+        // the test profile only. Outside of tests, application.properties 
resolves them from the environment.
         result.put("camel.vault.cyberark.username", 
result.get("conjur.reader.username"));
         result.put("camel.vault.cyberark.apiKey", 
result.get("conjur.reader.apiKey"));
 

Reply via email to