From 81b24ec1afad4c947a972b8c7f834806d7c0205e Mon Sep 17 00:00:00 2001 From: Anthony Lukach Date: Thu, 4 Jun 2026 23:18:52 -0700 Subject: [PATCH] feat(oidc-provider): make OidcCredentialProvider/CredentialCache cheaply cloneable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Put the cache's entries map behind an Arc and derive Clone on CredentialCache and OidcCredentialProvider. Cloning a provider now shares the same cache, so a runtime that rebuilds its dispatch chain per request (e.g. a Cloudflare Worker) can hold one provider in a shared/static slot and reuse it across requests — keeping the credential cache warm instead of re-minting a JWT and re-running AssumeRoleWithWebIdentity on every call. No behavior change for existing single-instance use. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/oidc-provider/src/cache.rs | 17 +++++++++-------- crates/oidc-provider/src/lib.rs | 5 +++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/oidc-provider/src/cache.rs b/crates/oidc-provider/src/cache.rs index 9ef156a..e684f52 100644 --- a/crates/oidc-provider/src/cache.rs +++ b/crates/oidc-provider/src/cache.rs @@ -16,21 +16,22 @@ use crate::BackendCredentials; const EXPIRY_MARGIN_SECS: i64 = 60; /// Thread-safe TTL cache for cloud credentials. +/// +/// `Clone` shares the same underlying store (the entries map is behind an +/// `Arc`), so a cloned [`OidcCredentialProvider`](crate::OidcCredentialProvider) +/// keeps hitting the same cache — letting a runtime hold the provider in a +/// shared/`static` slot and reuse it across requests instead of re-minting and +/// re-exchanging every time. +#[derive(Clone, Default)] pub struct CredentialCache { - entries: Mutex>>, -} - -impl Default for CredentialCache { - fn default() -> Self { - Self::new() - } + entries: Arc>>>, } impl CredentialCache { /// Create an empty credential cache. pub fn new() -> Self { Self { - entries: Mutex::new(HashMap::new()), + entries: Arc::new(Mutex::new(HashMap::new())), } } diff --git a/crates/oidc-provider/src/lib.rs b/crates/oidc-provider/src/lib.rs index 18d642d..a383a00 100644 --- a/crates/oidc-provider/src/lib.rs +++ b/crates/oidc-provider/src/lib.rs @@ -56,6 +56,11 @@ pub trait HttpExchange: } /// Top-level provider that combines signing, exchange, and caching. +/// +/// `Clone` is cheap and shares the credential cache (and the `Clone` HTTP +/// client), so a runtime can construct one provider and reuse it across requests +/// — keeping the cache warm instead of re-minting + re-exchanging every call. +#[derive(Clone)] pub struct OidcCredentialProvider { signer: JwtSigner, cache: CredentialCache,