You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
walletkit-core/src/authenticator/mod.rs:513-523 drops the newly minted session_id_r_seed returned by a ProofType::CreateSession proof request. The storage-side caching block keys off the request'ssession_id, which is always None for CreateSession, so the seed is never persisted — even though the response carries a valid newly-minted session_id that would be the correct cache key.
(Lookup is fine — for a CreateSession request there's nothing to look up, by definition. The bug is purely on the storage side, after the core authenticator has minted the new session.)
proof_request.0.session_id is None (the RP doesn't have a session yet) → the inner if let is skipped.
result.session_id_r_seed is Some(new_seed) and result.proof_response.session_id is Some(new_session_id), both available — but only proof_request.0.session_id is consulted, so the cache write is skipped.
For Session requests, proof_request.0.session_id is Some, so the current path works.
Impact
Correctness is preserved because the core authenticator's Session branch (world-id-protocol/crates/authenticator/src/prove.rs:319-326) handles a missing cached seed by re-deriving via OPRF from session_id.oprf_seed. The functional cost is one extra OPRF round-trip on the firstSession request after a CreateSession, after which caching fills correctly on that Session path.
So: a performance regression on CreateSession → Session transitions, not a broken flow.
Proposed fix
Cache under result.proof_response.session_id.oprf_seed instead of proof_request.0.session_id.oprf_seed. The response's session_id is correct in both flows:
CreateSession: response carries the newly minted session_id.
Session: response echoes the request's session_id (same oprf_seed).
Currently masked by walletkit-core/tests/proof_generation_integration.rs, which primes the store via store.store_session_seed(...) directly before the Session proof, bypassing the caching block.
Summary
walletkit-core/src/authenticator/mod.rs:513-523drops the newly mintedsession_id_r_seedreturned by aProofType::CreateSessionproof request. The storage-side caching block keys off the request'ssession_id, which is alwaysNoneforCreateSession, so the seed is never persisted — even though the response carries a valid newly-mintedsession_idthat would be the correct cache key.(Lookup is fine — for a
CreateSessionrequest there's nothing to look up, by definition. The bug is purely on the storage side, after the core authenticator has minted the new session.)Code
For
CreateSession:proof_request.0.session_idisNone(the RP doesn't have a session yet) → the innerif letis skipped.result.session_id_r_seedisSome(new_seed)andresult.proof_response.session_idisSome(new_session_id), both available — but onlyproof_request.0.session_idis consulted, so the cache write is skipped.For
Sessionrequests,proof_request.0.session_idisSome, so the current path works.Impact
Correctness is preserved because the core authenticator's
Sessionbranch (world-id-protocol/crates/authenticator/src/prove.rs:319-326) handles a missing cached seed by re-deriving via OPRF fromsession_id.oprf_seed. The functional cost is one extra OPRF round-trip on the firstSessionrequest after aCreateSession, after which caching fills correctly on thatSessionpath.So: a performance regression on
CreateSession → Sessiontransitions, not a broken flow.Proposed fix
Cache under
result.proof_response.session_id.oprf_seedinstead ofproof_request.0.session_id.oprf_seed. The response'ssession_idis correct in both flows:CreateSession: response carries the newly mintedsession_id.Session: response echoes the request'ssession_id(same oprf_seed).Sketch:
Notes
chore: bump world-id-protocol to v0.11.0).walletkit-core/tests/proof_generation_integration.rs, which primes the store viastore.store_session_seed(...)directly before theSessionproof, bypassing the caching block.