-
Notifications
You must be signed in to change notification settings - Fork 100
Description
Is your feature request related to a problem? Please describe.
The MSAL Go library for confidential client applications lacks sophisticated token caching mechanisms. Currently, every call to AcquireTokenByCredential() hits the network even when we have a valid cached token, leading to:
- Performance overhead - Unnecessary network requests for tokens that are still valid
- Race conditions - Concurrent token requests can cause multiple simultaneous calls to the identity provider
- Manual token management - Applications must manually check token expiry and handle renewal
- Missing enterprise features - While other MSAL libraries have basic caching, none provide the advanced auto-renewal capabilities needed for production systems
This is particularly problematic in high-traffic microservices where token acquisition becomes a bottleneck, and in long-running services where automatic token renewal would significantly improve reliability.
Describe the solution you'd like
I'd like to see an enhanced confidential client with thread-safe token caching and automatic renewal capabilities:
// New enhanced client with built-in caching
client, err := confidential.NewEnhancedClient(authority, clientID, cred)
// Automatic caching and renewal (returns cached token if valid)
result, err := client.AcquireTokenByCredentialWithCaching(ctx, scopes)
// Force refresh when needed
result, err := client.ForceRefreshToken(ctx, scopes)
// Cache management and monitoring
client.ClearTokenCache()
stats := client.GetCacheStats()Key features:
- Thread-safe caching using
sync.RWMutexfor concurrent access - Automatic token renewal with configurable buffer time (default: 2 minutes before expiry)
- Token reuse - Return cached tokens when still valid
- Force refresh capability - Explicit control over token refresh
- Cache statistics - Monitoring and debugging capabilities
- Backward compatibility - New
EnhancedClienttype alongside existingClient
Describe alternatives you've considered
-
Manual implementation - I've created a custom
msal-extensions-golibrary with these features, but this fragments the ecosystem and requires maintaining separate code -
Using existing cache accessor - The current
WithCache()option only handles persistence, not intelligent token reuse or auto-renewal -
Wrapping the existing client - I could wrap
confidential.Clientwith my own caching layer, but this adds complexity and doesn't integrate with the library's internal token management -
Using external token management libraries - Third-party solutions exist, but they don't integrate seamlessly with MSAL's authentication flows and token formats
-
Accepting the current limitations - Simply living with the performance overhead, but this becomes problematic at scale
The best solution is to integrate this functionality directly into the official library, providing capabilities that would be valuable across all MSAL libraries.
Additional context
This feature request addresses a gap that exists across MSAL libraries - while they have basic caching, none provide the sophisticated auto-renewal capabilities needed for production enterprise applications.
Related existing issues:
- [Bug] Concurrent managedidentity.Client.AcquireToken() calls cause multiple token requests to identity provider before caching #569: "Concurrent managedidentity.Client.AcquireToken() calls cause multiple token requests" - Shows the concurrency problem exists
- [Feature Request] When doing a force refresh in and AAD is not down (5xx) we remove the refresh_in from cache #555: "When doing a force refresh in and AAD is not down (5xx) we remove the refresh_in from cache" - Indicates interest in cache management
- [Bug] managedidentity.Client token's early RefreshOn is not saved in the cache #570: "managedidentity.Client token's early RefreshOn is not saved in the cache" - Shows cache-related bugs
I'm willing to contribute the implementation code and comprehensive tests if this feature is accepted. The implementation would follow the existing library patterns and maintain backward compatibility.