From a4ea5b06c06cd47edec5315e6c520b2669a3a568 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Fri, 21 Aug 2026 12:46:40 +0700 Subject: [PATCH 1/2] [service-utils] Scope service-key auth cache by teamId; drop timestampless cache entries --- .changeset/spicy-donuts-argue.md | 5 +++++ packages/service-utils/src/core/authorize/index.ts | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .changeset/spicy-donuts-argue.md diff --git a/.changeset/spicy-donuts-argue.md b/.changeset/spicy-donuts-argue.md new file mode 100644 index 00000000000..53b28e299e0 --- /dev/null +++ b/.changeset/spicy-donuts-argue.md @@ -0,0 +1,5 @@ +--- +"@thirdweb-dev/service-utils": patch +--- + +Scope service-key authorization cache entries by teamId, and ignore cache entries that lack a timestamp diff --git a/packages/service-utils/src/core/authorize/index.ts b/packages/service-utils/src/core/authorize/index.ts index 087a68ae34f..ba99caa554d 100644 --- a/packages/service-utils/src/core/authorize/index.ts +++ b/packages/service-utils/src/core/authorize/index.ts @@ -49,8 +49,8 @@ export async function authorize( // Use a separate cache key per auth method. const cacheKey = authData.incomingServiceApiKey - ? // incoming service key + clientId case - `key-v2:service-key:${authData.incomingServiceApiKeyHash}:${authData.clientId ?? "client_default"}` + ? // incoming service key + teamId + clientId case + `key-v2:service-key:${authData.incomingServiceApiKeyHash}:${authData.teamId ?? "team_default"}:${authData.clientId ?? "client_default"}` : authData.secretKeyHash ? // secret key case `key-v2:secret-key:${authData.secretKeyHash}` @@ -80,8 +80,6 @@ export async function authorize( if (diff < cacheTtlMs) { teamAndProjectResponse = parsed.teamAndProjectResponse; } - } else { - teamAndProjectResponse = parsed; } } } catch { From 7e8644026f6e9681e03bc7b666af6aab25c21048 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Fri, 21 Aug 2026 12:52:29 +0700 Subject: [PATCH 2/2] [service-utils] Do not cache service-key auth without a tenant selector --- packages/service-utils/src/core/authorize/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/service-utils/src/core/authorize/index.ts b/packages/service-utils/src/core/authorize/index.ts index ba99caa554d..169f915debf 100644 --- a/packages/service-utils/src/core/authorize/index.ts +++ b/packages/service-utils/src/core/authorize/index.ts @@ -50,7 +50,10 @@ export async function authorize( // Use a separate cache key per auth method. const cacheKey = authData.incomingServiceApiKey ? // incoming service key + teamId + clientId case - `key-v2:service-key:${authData.incomingServiceApiKeyHash}:${authData.teamId ?? "team_default"}:${authData.clientId ?? "client_default"}` + // do not cache service-key requests that carry no tenant selector + authData.teamId || authData.clientId + ? `key-v2:service-key:${authData.incomingServiceApiKeyHash}:${authData.teamId ?? "team_default"}:${authData.clientId ?? "client_default"}` + : null : authData.secretKeyHash ? // secret key case `key-v2:secret-key:${authData.secretKeyHash}`