diff --git a/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs b/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs
new file mode 100644
index 000000000..00b5dc117
--- /dev/null
+++ b/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Duende Software. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+namespace Duende.AccessTokenManagement;
+
+public interface IClientCredentialsCacheDurationStore
+{
+ ///
+ /// Gets the expiration duration for the specified client credentials cache key.
+ ///
+ /// The cache key identifying the client credentials.
+ ///
+ /// A representing the duration until the cache entry expires.
+ ///
+ TimeSpan GetExpiration(ClientCredentialsCacheKey cacheKey);
+
+ ///
+ /// Sets the expiration for the specified client credentials cache key.
+ ///
+ /// The cache key identifying the client credentials.
+ /// The expiration time to set for the cache entry.
+ ///
+ /// A representing the duration until the cache entry expires after setting.
+ ///
+ TimeSpan SetExpiration(ClientCredentialsCacheKey cacheKey, DateTimeOffset expiration);
+}
diff --git a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs
index 9f0960f15..068c696a2 100644
--- a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs
+++ b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs
@@ -11,7 +11,7 @@ namespace Duende.AccessTokenManagement.Internal;
///
internal sealed class ClientCredentialsCacheDurationStore(
IOptions options,
- TimeProvider time)
+ TimeProvider time) : IClientCredentialsCacheDurationStore
{
private readonly ClientCredentialsTokenManagementOptions _options = options.Value;
private readonly ConcurrentDictionary _cacheDurations = new();
diff --git a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs
index 7a0a877ac..dcfc923cd 100644
--- a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs
+++ b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs
@@ -17,7 +17,7 @@ internal class ClientCredentialsTokenManager(
TimeProvider time,
IClientCredentialsTokenEndpoint client,
IClientCredentialsCacheKeyGenerator cacheKeyGenerator,
- ClientCredentialsCacheDurationStore cacheDurationAutoTuningStore,
+ IClientCredentialsCacheDurationStore cacheDurationAutoTuningStore,
ILogger logger
) : IClientCredentialsTokenManager
{
diff --git a/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs b/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs
index ac2c09c27..d6857af00 100644
--- a/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs
+++ b/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs
@@ -41,7 +41,7 @@ public static ClientCredentialsTokenManagementBuilder AddClientCredentialsTokenM
this IServiceCollection services)
{
services.TryAddTransient();
- services.TryAddSingleton();
+ services.TryAddSingleton();
services.AddHybridCache();
// Add a default serializer for ClientCredentialsToken
diff --git a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt
index fec49dd29..a4ba1edf9 100644
--- a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt
+++ b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt
@@ -26,6 +26,7 @@ Duende.AccessTokenManagement.ForceTokenRenewal
Duende.AccessTokenManagement.HttpRequestContext
Duende.AccessTokenManagement.HybridCacheConstants
Duende.AccessTokenManagement.IClientAssertionService
+Duende.AccessTokenManagement.IClientCredentialsCacheDurationStore
Duende.AccessTokenManagement.IClientCredentialsCacheKeyGenerator
Duende.AccessTokenManagement.IClientCredentialsTokenEndpoint
Duende.AccessTokenManagement.IClientCredentialsTokenManager
diff --git a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt
index ee596b9d7..19ed96613 100644
--- a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt
+++ b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt
@@ -149,6 +149,11 @@
{
System.Threading.Tasks.Task GetClientAssertionAsync(Duende.AccessTokenManagement.ClientCredentialsClientName? clientName = default, Duende.AccessTokenManagement.TokenRequestParameters? parameters = null, System.Threading.CancellationToken ct = default);
}
+ public interface IClientCredentialsCacheDurationStore
+ {
+ System.TimeSpan GetExpiration(Duende.AccessTokenManagement.ClientCredentialsCacheKey cacheKey);
+ System.TimeSpan SetExpiration(Duende.AccessTokenManagement.ClientCredentialsCacheKey cacheKey, System.DateTimeOffset expiration);
+ }
public interface IClientCredentialsCacheKeyGenerator
{
Duende.AccessTokenManagement.ClientCredentialsCacheKey GenerateKey(Duende.AccessTokenManagement.ClientCredentialsClientName clientName, Duende.AccessTokenManagement.TokenRequestParameters? parameters = null);