Repository navigation
test(scheduledauth): tolerate go-oidc's in-flight JWKS reuse in the failed-refresh test - #1231
Conversation
…ailed-refresh test go-oidc's RemoteKeySet.keysFromRemote marks the in-flight fetch done before it takes the lock and clears r.inflight (oidc/jwks.go:196-234, v3.18.0). A Validate that starts right after the previous one returned can still see the finished in-flight fetch and reuse its cached error without a new HTTP request, so "every token causes a fetch" is not guaranteed by the library and the test failed on Linux CI. The invariant under test is that a failed refresh does not put the kid in the negative cache. Require a fetch per token within a bounded 2s retry instead, with every call still returning ErrUnauthorized, and keep the final negative-cache-empty assertion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
VERDICT: APPROVE 10e65d1 PR #1231, test(scheduledauth): tolerate go-oidc's in-flight JWKS reuse. Diff: internal/server/scheduledauth/kidguard_test.go +13/-5, test-only. Root cause: confirmed independently.
Findings
Attacked
|
|
Independent review 2 (claude-fleet, cold): APPROVE 10e65d1 The go-oidc claim holds for the vendored version, and I reproduced the base flake. The head test did not flake across about 13,500 runs. Every mutation that caches the kid or skips the fetch fails the new test every time. Findings (none blocking):
Attacked:
Verified locally, on a
Reviewed by an independent agent with no author context (second reviewer). Review only: nothing was pushed, and the GitHub review state is unchanged. |
|
Local verification at
|
Main CI went red after #1164 (
b6a0649a, run 39496496066).TestValidate_OIDC_FailedRefreshDoesNotCacheKidfailed atkidguard_test.go:208with "token 1: no JWKS fetch although no refresh ever confirmed the kid unknown". 500 local runs pass. The production behaviour is correct; the test assumption is not.Cause: go-oidc v3.18.0's
RemoteKeySet.keysFromRemote(oidc/jwks.go:196-234) signalsinflight.donebefore it takes the lock and setsr.inflight = nil. AValidatethat arrives right after the previous one returned can pick up the finished in-flight request and get its result without a new HTTP fetch. "Every token after a failed refresh causes a fetch" is therefore not guaranteed.Change (test only): for each token, retry
Validateuntil a fetch is observed, with a 2s deadline. Every call must still returnErrUnauthorized. That still proves the invariant: a failed refresh does not put the kid in the negative cache, so a later token can refresh. The finalnegativeKidCount == 0check is unchanged. No production code changes.Evidence:
inflight.done. Under it the old assertion fails with the CI message and the new one passes. The wholeTestValidate_OIDC_group passes under the same delay (-count=20), including the two exact-one-fetch siblings.go test -race -count=300 -run 'TestValidate_OIDC_' ./internal/server/scheduledauth/passes.rememberIfConfirmedto cache the kid on any failure makes the new test fail ("token 1: no JWKS fetch within 2s").go build ./...,go vet ./...andmake lintare clean, and pre-commit passes.cc @IAmJSD (author of #1164).
🤖 Generated with Claude Code
Summary by CodeRabbit