oscerd opened a new pull request, #28094: URL: https://github.com/apache/camel/pull/28094
Fixes [CAMEL-25797](https://issues.apache.org/jira/browse/CAMEL-25797). `KeyRotationScheduler` documents three rotation signals — key age, usage count, and a `PENDING_ROTATION` status. Two of the three could never trigger. ## 1. `usageCount` was only advanced for stateful keys `KeyMetadata.updateLastUsed()` is the only thing that increments the counter, and its single production caller sat inside `persistStatefulKeyStateAfterSign()` behind: ```java long remaining = getStatefulKeyRemaining(privateKey); if (remaining < 0) { // Not a stateful key return; } ``` So for ML-DSA, SLH-DSA, Falcon and every KEM key — the overwhelming majority — the counter stayed at `0` forever, while all five lifecycle managers gate on `maxUsage > 0 && metadata.getUsageCount() >= maxUsage`. `setMaxKeyUsage` and the documented `camel.component.pqc.key-rotation-max-usage` property were inert. The method is now `recordKeyUsageAfterSign()`. It advances and persists the usage count for **every** key, and re-stores the key pair itself only for the stateful algorithms, where the advanced one-time index has to survive a restart. That also drops a redundant remote write per signature for non-stateful keys — they previously did a `storeKey` only in the stateful branch, so this strictly reduces traffic relative to what stateful keys already do while finally recording usage for the rest. ## 2. `PENDING_ROTATION` was filtered out before it was read ```java private Predicate<KeyMetadata> keyFilter = metadata -> metadata.getStatus() == KeyMetadata.KeyStatus.ACTIVE; ``` `KeyMetadata.needsRotation()` does test for `PENDING_ROTATION`, but a key marked that way is no longer `ACTIVE`, so the scheduler `continue`d past it at the filter before `needsRotation()` was ever consulted. Only `nextRotationAt` on an otherwise-ACTIVE key actually worked. The default filter now accepts `ACTIVE` and `PENDING_ROTATION`. A filter supplied via `setKeyFilter` is unaffected. Javadoc on the class and on `setKeyFilter` updated to match. ## Tests New `KeyRotationSignalsTest`: - `signingAStatelessKeyAdvancesTheUsageCount` — three ML-DSA signatures, asserts the count reaches 3 and that `needsRotation(.., maxUsage=3)` then reports true; - `aPendingRotationKeyIsSelectedByTheDefaultFilter` — asserts the default filter accepts the key and that `checkAndRotate()` actually rotates it. Against `main`: `expected: <3> but was: <0>` and `expected: <true> but was: <false>`. Full `camel-pqc` build green: 241 tests, 0 failures, no regenerated-file drift. ## Scope note Usage is recorded on the signing paths, which are the ones that already had the hook. A pure-KEM deployment still will not advance `usageCount`; extending the hook to the KEM operations is a larger behavioural change and is better done separately if wanted. ## Upgrade guide Added a 4.24 entry. This makes previously-inert configuration take effect, so a deployment that already set `maxKeyUsage` may rotate on the first check once the counter starts moving — worth flagging before upgrade. --- _Reported, analysed and fixed by Claude Code (AI agent) on behalf of @oscerd._ 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
