This fix is now available in kura@0.9.1. Update to this version to resolve the authenticate cache misses caused by per-request headers like grpc-timeout and traceparent.
Hive
fix(kura): key extension hook caches on credential headers only
GitHub issue · Closed
What changed
The extension authenticate/authorize cache key now fingerprints only credential-bearing request headers (authorization, proxy-authorization, cookie, x-api-key) instead of hashing every header minus a small noise denylist (accept, content-length, host, user-agent, x-request-id).
Root cause
REAPI clients attach a deadline to every RPC, which arrives as a grpc-timeout header whose value is the remaining time at send — effectively unique on every request. Because the old fingerprint hashed all-headers-minus-denylist, every deadline-carrying request produced a fresh cache key, so the authenticate cache missed almost permanently. Trace propagation headers (traceparent) have the same effect on HTTP traffic.
Every miss re-runs the authenticate hook; with the Tuist hook that means a POST /oauth2/introspect round-trip to the control plane per miss.
Observed during a single cold bazel build of the Kura crate graph against a dev node (no local JWT verifier, so each miss introspects):
- authenticate cache: 15,340 misses vs 13,174 hits (~54% miss rate)
- ~6,800 introspection requests hit the control plane, pinning the Phoenix server’s BEAM at ~300% CPU for the duration of the build
Production nodes are affected the same way — real traffic carries grpc-timeout and traceparent — just with the introspection volume spread across the fleet.
Why this solution
The function is named credentials_fingerprint and the cache is documented as “per credentials”; the denylist approach was an under-approximation of that intent that silently broke whenever clients sent any per-request header. An allowlist of credential headers makes the intent hold structurally. Hooks that authenticate from non-standard inputs can still opt out of caching via a short/absent ttl_seconds — documented in the README.
Validation
- New regression test: same credentials with varying
grpc-timeout/traceparentreuse the cached result (identity backend called once); a differentauthorizationvalue does not share the cache entry. cargo test extension::— 24 passed.cargo clippy --all-targets -- -D warnings— clean.- Live validation on a dev kind node running this patch, driving comparable Bazel build volume (a full re-upload pass plus incremental/no-op builds): authenticate cache went to 11,444 hits / 14 misses (99.9% hit rate) and total introspection calls for the whole session dropped from ~6,800 to 14.
🤖 Generated with Claude Code