fix(gateway): fingerprint full auth token in agent cache signature (#3247)
Previously _agent_config_signature() used only the first 8 characters of the API key, which causes false cache hits for JWT/OAuth tokens that share a common prefix (e.g. 'eyJhbGci'). This led to cross-account cache collisions when switching OAuth accounts in multi-user gateway deployments. Replace the 8-char prefix with a SHA-256 hash of the full key so the signature is unique per credential while keeping secrets out of the cache key. Salvaged from PR #3117 by EmpireOperating. Co-authored-by: EmpireOperating <EmpireOperating@users.noreply.github.com>
This commit is contained in:
@@ -4684,10 +4684,18 @@ class GatewayRunner:
|
||||
prompt cache hits.
|
||||
"""
|
||||
import hashlib, json as _j
|
||||
|
||||
# Fingerprint the FULL credential string instead of using a short
|
||||
# prefix. OAuth/JWT-style tokens frequently share a common prefix
|
||||
# (e.g. "eyJhbGci"), which can cause false cache hits across auth
|
||||
# switches if only the first few characters are considered.
|
||||
_api_key = str(runtime.get("api_key", "") or "")
|
||||
_api_key_fingerprint = hashlib.sha256(_api_key.encode()).hexdigest() if _api_key else ""
|
||||
|
||||
blob = _j.dumps(
|
||||
[
|
||||
model,
|
||||
runtime.get("api_key", "")[:8], # first 8 chars only
|
||||
_api_key_fingerprint,
|
||||
runtime.get("base_url", ""),
|
||||
runtime.get("provider", ""),
|
||||
runtime.get("api_mode", ""),
|
||||
|
||||
@@ -48,6 +48,28 @@ class TestAgentConfigSignature:
|
||||
sig2 = GatewayRunner._agent_config_signature("claude-opus-4.6", runtime, ["hermes-telegram"], "")
|
||||
assert sig1 != sig2
|
||||
|
||||
def test_same_token_prefix_different_full_token_changes_signature(self):
|
||||
"""Tokens sharing a JWT-style prefix must not collide."""
|
||||
from gateway.run import GatewayRunner
|
||||
|
||||
rt1 = {
|
||||
"api_key": "eyJhbGci.token-for-account-a",
|
||||
"base_url": "https://chatgpt.com/backend-api/codex",
|
||||
"provider": "openai-codex",
|
||||
"api_mode": "codex_responses",
|
||||
}
|
||||
rt2 = {
|
||||
"api_key": "eyJhbGci.token-for-account-b",
|
||||
"base_url": "https://chatgpt.com/backend-api/codex",
|
||||
"provider": "openai-codex",
|
||||
"api_mode": "codex_responses",
|
||||
}
|
||||
|
||||
assert rt1["api_key"][:8] == rt2["api_key"][:8]
|
||||
sig1 = GatewayRunner._agent_config_signature("gpt-5.3-codex", rt1, ["hermes-telegram"], "")
|
||||
sig2 = GatewayRunner._agent_config_signature("gpt-5.3-codex", rt2, ["hermes-telegram"], "")
|
||||
assert sig1 != sig2
|
||||
|
||||
def test_provider_change_different_signature(self):
|
||||
from gateway.run import GatewayRunner
|
||||
|
||||
|
||||
Reference in New Issue
Block a user