Closed weihong-xu-hpe closed 1 month ago
Sorry, please disregard my earlier response. I thought you were talking about a synchronization issue in jwk.Cache
, but I don't think it is.
You need an explicit lock around your loop.
mu.Lock() // WRITE lock
for i := 0; i < set.Len(); i++ {
p.localKeySet.AddKey(...)
}
mu.Unlock()
The lock in p.localKeySet can only protect the p.localKeySet from concurrent read/write during the method call. For example, w/o a write lock in the localKeySet
, and if you were reading an element from position i
while some other thread is writing to the same position i
(which may include truncating the container slice), the results might be wrong. The lock inside the key protects from that.
However, what you are doing is to change the entirety of the p.localKeySet, which means you need to protect YOUR ENTIRE WRITE OPERATION (the for loop) with a lock. You will also need to protect your other threads from reading from p.localKeySet
while you are writing to it.
P.S. I have a feeling you should be able to get away with just swapping the entire p.localKeySet
with the new JWKS if you properly protect access to it.
sorry, I think I misspoke. the write lock needs to start when you check for the existence of a key. (not 100% sure, b/c I'm writing this as I commute)
Either way you need to lock, not jwx
Okay, understand, I think better for me is introduce singleflight around the time the rotation happens. Great thx for your help
Describe the bug Due to the token issuer behaviour, my team try to implement a logic like below:
Our service currently has close to 100 RPS on one instance, the download of the jwks could takes up to 1 second.
Based on the code reads, the AddKey logic should be in jwk/set.go@AddKey , that part has a RWmutex, the comment around the set all describe if the key exists in that local keyset, I should see a following message throw out as error.
Instead in our production log what we saw is
The localKeySet add the same key again and again, cause the localKeySet grows.
The value I print above is the kid of that key.
Sample code logic:
Software Version GO : go version go1.23.0 darwin/arm64 Library : github.com/lestrrat-go/jwx/v2 v2.1.1
To Reproduce / Expected behavior
Expected behaviour: local jwks should contain only old and new key What happens: New key add multiple times