[ 
https://issues.apache.org/jira/browse/CAMEL-25518?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Work on CAMEL-25518 started by shashank.
----------------------------------------
> camel-hashicorp-vault - secret refresh never detects updates of secrets 
> outside the "secret" engine, nor updates made before its first check
> --------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25518
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25518
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-hashicorp-vault
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> The secret refresh added by CAMEL-22676 
> ({{camel.vault.hashicorp.refreshEnabled=true}}) polls 
> {{<engine>/metadata/<secret>}} for every tracked secret. Besides the names 
> listed in {{camel.vault.hashicorp.secrets}}, it tracks every secret resolved 
> with the {{hashicorp:}} properties function; when that option is not set, the 
> documentation says the task takes into account all the properties with a 
> {{hashicorp:}} prefix.
> 1. {{HashicorpVaultPropertiesFunction.getSecretFromSource}} records only the 
> key: {{secrets.add(key)}} (line 214 at main c578a42a776d), so 
> {{hashicorp:kv:db#password}} is recorded as {{db}}. 
> {{HashicorpVaultReloadTriggerTask.buildMetadataPath}} (lines 272-297) reads a 
> name without an engine from the {{secret}} engine, so it reads 
> {{secret/metadata/db}}, which does not exist; {{VaultTemplate.read}} returns 
> null and the task skips it without a log. For a secret in any engine other 
> than {{secret}} (for example {{kv}}), an update never triggers a reload 
> unless the user also lists it as {{kv:db}} in 
> {{camel.vault.hashicorp.secrets}}.
> 2. The first run of the task only records the version it reads (lines 
> 212-215: "First time seeing this secret, just record the version"). The first 
> run happens one refresh period after startup (60 s by default). If the secret 
> is updated in that window, the new version becomes the baseline and the 
> application keeps the value it resolved at startup until the secret changes 
> again.
> h3. Reproduction
> New {{HashicorpVaultReloadTriggerTaskTest}} with a minimal in-process fake of 
> the Vault KV v2 HTTP API (JDK {{HttpServer}}, no container): resolve 
> {{hashicorp:kv:db#password}} (version 1), run the task, set version 2, run 
> the task; and resolve {{hashicorp:secret:api#password}} (version 1), set 
> version 2, run the task. On main:
> {noformat}
> rotationInNonDefaultEngineIsDetected: the refresh task must read the metadata 
> of the engine the secret was resolved from, but read [secret/metadata/db, 
> secret/metadata/db] ==> expected: <true> but was: <false>
> rotationBeforeFirstCheckIsDetected: the application resolved version 1 but 
> version 2 was not detected, updates: {} ==> expected: <false> but was: <true>
> secretsAreTrackedWithTheirEngine: expected: <[api, kv:db]> but was: <[api, 
> db]>
> {noformat}
> h3. Proposed fix
> The properties function records the secret in the format of 
> {{camel.vault.hashicorp.secrets}}: {{engine:secret}}, or only {{secret}} for 
> the default {{secret}} engine (so the names of secrets in the {{secret}} 
> engine do not change, and a resolved secret has the same name as when it is 
> listed in the option, so it is not checked twice). It also remembers the 
> version it read ({{data.metadata.version}} of the KV v2 response; not when a 
> specific {{@version}} was requested). For a secret the task has not seen 
> before, it starts from that version, so a newer version in Vault triggers a 
> reload at the first check. {{getSecrets()}} and the task's updates now name 
> secrets of other engines {{engine:secret}}; component docs and a 4.23 upgrade 
> guide note updated. The recorded set and the new version map are concurrent 
> collections, as the refresh task reads them from its own thread. 
> camel-hashicorp-vault unit tests: 6, 0 failures (the ITs need a Vault 
> container and were not run).
> Found with a TLA+ model of startup resolution, rotations and the check runs 
> (metadata read, version compare, reload): "after a complete check run with no 
> update since it started, the application uses the current version of every 
> secret" is violated for a {{kv}} secret relying on auto-detection (12 steps: 
> resolve, two check runs around one update, no reload) and for an update 
> before the first check (8 steps); it holds on main for the {{secret}} engine 
> with updates after the first check, and with 
> {{camel.vault.hashicorp.secrets=kv:db}}. With the fix it holds for two 
> secrets in different engines with two updates at any time. Then confirmed 
> with the real classes as above.
> Workaround on affected versions: list every secret of a non-default engine as 
> {{engine:secret}} in {{camel.vault.hashicorp.secrets}} (fixes 1, not 2).
> Affected: 4.17.0 and later (camel-4.18.x and camel-4.22.x have the same code; 
> camel-4.14.x has no secret refresh).
> Duplicate check (2026-10-09): JIRA component camel-hashicorp-vault (7 issues, 
> none about the refresh), text "HashicorpVaultReloadTriggerTask" (none), 
> "hashicorp" with "refresh"/"reload"/"engine" (9; CAMEL-22676/22677 added the 
> feature, CAMEL-24636 is the re-authentication SPI); GitHub pull requests 
> "hashicorp refresh", "HashicorpVaultReloadTriggerTask": none; no open PR 
> touches camel-hashicorp-vault.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to