Skip to content

fix: eliminate TOCTOU cache stampede in cachingClientCreator - #593

Open
adityakrmishra wants to merge 2 commits into
palantir:developfrom
adityakrmishra:fix/cache-stampede
Open

fix: eliminate TOCTOU cache stampede in cachingClientCreator#593
adityakrmishra wants to merge 2 commits into
palantir:developfrom
adityakrmishra:fix/cache-stampede

Conversation

@adityakrmishra

Copy link
Copy Markdown

Description

Resolves a TOCTOU (Time-of-Check to Time-of-Use) race condition in cachingClientCreator that causes a cache stampede against the GitHub API.

Problem:
Under concurrent load (e.g., webhook bursts), multiple goroutines requesting a token for the same installationID simultaneously miss the LRU cache. This results in N redundant HTTP requests to GitHub before the cache is populated, risking rate limit exhaustion.

Solution:
Implemented golang.org/x/sync/singleflight around the delegate call.

  • All concurrent requests for the same installation key now block and share the result of a single in-flight API call.
  • Added a double-checked Get inside the closure to safely catch races where the cache was populated just before the lock.

Proof of Work (Test Results)

Added TestCacheStampede_Vulnerable which fires 100 concurrent requests for the same installationID.

Before Patch:

Concurrent Goroutines: 100
GitHub API Delegate Calls: ~100 (Redundant)

After Patch:

Concurrent Goroutines: 100
GitHub API Delegate Calls: 1 (Optimized)

Under concurrent load, multiple goroutines calling NewInstallationClient
or NewInstallationV4Client for the same installation ID could all miss
the LRU cache simultaneously (TOCTOU race between Get and Add) and each
proceed to call the delegate — resulting in N redundant token-fetch HTTP
requests to the GitHub API.

Fix by wrapping the slow delegate call in a singleflight.Group so only
one in-flight request per installation key is made; all other concurrent
callers share the result. A double-checked Get inside the singleflight
closure ensures the cache is used if a prior call already populated it.

Adds TestCacheStampede_Vulnerable to prove the fix: 100 goroutines
result in exactly 1 delegate invocation after the patch.

Fixes: TOCTOU race in cachingClientCreator.NewInstallationClient
@changelog-app

changelog-app Bot commented Jul 23, 2026

Copy link
Copy Markdown

Successfully generated changelog entry!

Entry generated via PR title

To modify this entry, edit PR title using proper format.


📋Changelog Preview

🐛 Fixes

  • Eliminate TOCTOU cache stampede in cachingClientCreator (#593)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant