Repository navigation
fix(helper): fail KeyStoreHelper.run when the X.509 context watch fails - #489
Merged
maxlambrecht merged 1 commit intoOct 29, 2026
Merged
Conversation
KeyStoreHelper's X.509 context watcher released the run latch and then threw a WatcherException from onError. DefaultWorkloadApiClient invokes watchers on gRPC executor threads, so the exception never reached the thread blocked in run: run returned normally, as if the KeyStore had been written. run(false) therefore reported success when the first X.509 context could not be fetched or stored, and the CLI, which uses run(true), exited with status 0 after a failed watch (for example PERMISSION_DENIED from the Workload API, or an update that could not be stored). The existing error test passed only because its stub calls onError synchronously on the caller's thread. Record the first error reported while run is waiting and throw it from run after the latch is released, so run fails with KeyStoreHelperException as documented and the CLI exits with status 1. Errors arriving after run has returned are only logged; previously the exception thrown from onError could also cancel the gRPC stream. Fixes spiffe#488 Signed-off-by: NopeCharon <115794254+NopeCharon@users.noreply.github.com>
maxlambrecht
force-pushed
the
fix/keystore-helper-async-watch-error
branch
from
October 29, 2026 19:41
7c95492 to
e8a7280
Compare
maxlambrecht
approved these changes
Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
KeyStoreHelper's X.509 context watcher no longer throws fromonError. It records the first error reported whilerunis waiting and releases the latch, andrunthrows that error, wrapped inKeyStoreHelperExceptionas before, once the latch is released. Errors that arrive afterrunhas returned are only logged.Fixes #488
Why
DefaultWorkloadApiClientcalls watchers on gRPC executor threads, so theWatcherExceptionthrown fromonErrornever reached the thread blocked inrun. That thread only saw the latch released, andrunreturned normally:run(false)reported success when the first X.509 context could not be fetched or stored.run(true). After a failed watch (for examplePERMISSION_DENIEDfrom the Workload API, or an update that could not be written to the KeyStore), it closed the helper and exited with status 0.The existing
testCreateKeyStoreHelper_throwsExceptionWhenNoUpdateCanBeFetcheddidn't catch this becauseWorkloadApiClientErrorStubcallsonErrorsynchronously, on the thread that calledrun.When the helper stops is unchanged: any watch error still ends
run, and nowrunreports it.How tested
KeyStoreHelperTest.testRun_errorReportedAsynchronously_throwsExceptionandtestRun_keepRunning_errorReportedAsynchronously_throwsExceptionuse a client that reports the watch error from another thread. Both fail without this change, becauserunreturns normally.tcp://127.0.0.1:<port>returnsPERMISSION_DENIEDfromFetchX509SVID, andKeyStoreHelperuses the default client. Before:run(true)returned normally. After: it threwKeyStoreHelperExceptioncaused byCancelling X.509 Context watch../gradlew buildon JDK 17.