[
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)