volcano-sh / volcano-sh/agentcube
TokenCache can return authenticated=true after JWT expiry due to sliding TTL (does not check exp)
@HarshitPal25 is already working on this.
Since Jun 4, 2026.
- Dominant language
- Go
- Stars
- 167
- Forks
- 88
- Avg merge
- 44m
- Merged PRs (30d)
- 1
Description
Summary
TokenCache.Get in pkg/workloadmanager/client_cache.go only checks how long ago the cache entry was last accessed (time.Since(entry.lastAccess) > c.ttl). Every time a cached token is used, lastAccess is reset to time.Now(), continuously pushing the expiry window forward. The token's actual JWT exp claim is never checked on cache hits. By contrast, ClientCache.Get (which caches K8s user clients) correctly parses the JWT expiry via parseJWTExpiry and evicts entries once the token has expired. TokenCache has parseJWTExpiry available but does not use it.
Affected code
func (c *TokenCache) Get(token string) (found bool, authenticated bool, username string) {
c.mu.Lock()
defer c.mu.Unlock()
entry, exists := c.cache[token]
if !exists {
return false, false, ""
}
// Only checks sliding lastAccess — token's real JWT exp is neververified
if time.Since(entry.lastAccess) > c.ttl {
c.lruList.Remove(entry.element)
delete(c.cache, token)
return false, false, ""
}
// Resets the window — a busy token never expires from cache
entry.lastAccess = time.Now()
c.lruList.MoveToFront(entry.element)
return true, entry.authenticated, entry.username
}
Reproduction scenario
- Use a K8s service-account token with a 1-minute lifetime.
- Validate it once so it gets cached in
TokenCacheasauthenticated=true. - Send requests every 4 minutes.
- Each hit updates
lastAccess, keeping the cache entry alive.
- Each hit updates
- After the token expires ,
TokenCachecontinues to return the cachedauthenticated=trueresult until there is a full 5-minute gap with no requests.
Expected behavior
TokenCache.Get should not return a cached authentication result once the JWT has expired (based on exp), even if requests keep arriving within the TTL window.
Actual behavior
TokenCache.Get can continue returning authenticated=true after the token has expired because only sliding lastAccess TTL is enforced.
Suggested fix
Store and enforce JWT expiry in tokenCacheEntry similar to clientCacheEntry:
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.