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

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


The following commit(s) were added to refs/heads/camel-quarkus-main by this 
push:
     new d8100e17 Avoid logging secrets and use RAW() property placeholders in 
the CyberArk Vault example
d8100e17 is described below

commit d8100e170360f43b615f0b3520d325bf6cdfda9a
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