Skip to content

fix: isolate quota cache entries per credential account - #236

Open
gitslim wants to merge 4 commits into
slkiser:mainfrom
gitslim:fix/credential-cache-key
Open

fix: isolate quota cache entries per credential account#236
gitslim wants to merge 4 commits into
slkiser:mainfrom
gitslim:fix/credential-cache-key

Conversation

@gitslim

@gitslim gitslim commented Aug 24, 2026

Copy link
Copy Markdown

Summary

The per-user disk quota cache (~/.cache/opencode/quota-provider-state/<provider>-<sha1(key)>.json) keyed entries without any account identity, so concurrent opencode instances that use different accounts for the same provider (e.g. different ZAI_API_KEY values via per-account wrapper scripts) clobbered each other's snapshots: last writer wins, and every other instance displays the wrong account's quotas until the cache TTL expires.

buildQuotaProviderStateCacheKey now appends an irreversible fingerprint (truncated sha1) of:

  • the allowlisted credential env values (ZAI_API_KEY, ZAI_CODING_PLAN_API_KEY, ZHIPU_*, MINIMAX_*, KIMI_*, ALIBABA_*, DEEPSEEK_API_KEY, KILO_API_KEY, CHUTES_API_KEY, OLLAMA_API_KEY, SYNTHETIC_API_KEY, NANOGPT_API_KEY, NANO_GPT_API_KEY, OPENCODE_API_KEY) to every key, and
  • custom quota-provider apiKeyEnv values to aggregate keys (the env var name was already part of the identity, but two accounts reusing the same name with different values still collided).

Design constraints preserved:

  • Raw credential values never enter a key — only a truncated one-way hash, so the existing "never credentials in aggregate identity" guarantee holds (the pre-existing test passes unchanged).
  • When no credential env vars are set, keys are byte-identical to legacy keys — single-account setups keep their cache warm across the upgrade.
  • options.credentialEnv is injectable so tests stay hermetic.

New module src/lib/credential-env.ts keeps the allowlist in one place, mirroring the per-provider envVars resolver lists.

Linked Issue

Fixes #235

OpenCode Validation

  • Current production released OpenCode version tested: 1.18.21
  • Why this version is relevant to the fix: the bug was traced on a live multi-instance setup (ZAI_API_KEY differing per instance) where instances alternately showed each other's five-hour/MCP quotas; the fix was validated on that setup.

Quality Checklist

  • I ran pnpm run typecheck
  • I ran pnpm run build
  • I ran pnpm test
  • This change is focused and avoids unrelated behavior changes
  • I updated or added tests when behavior changed
  • I updated docs when user-facing workflow, command, or config behavior changed
  • For provider changes, I followed Provider Changes, or this does not apply

(pnpm verify gate passes locally: 181 test files / 2175 tests, Biome clean, package contents verified. Docs checklist ticked as N/A — no user-facing workflow/config surface changes; the cache key is an internal detail.)

gitslim and others added 4 commits August 24, 2026 03:34
The per-user disk quota cache keyed entries without any account
identity, so concurrent opencode instances using different accounts
for the same provider (e.g. different ZAI_API_KEY values) clobbered
each other's snapshots and displayed the wrong account's quotas until
TTL expiry.

Add an irreversible fingerprint (truncated sha1) of the allowlisted
credential env values to every cache key, and of custom quota-provider
apiKeyEnv values to aggregate keys. Raw credential values never enter
a key; when no credential env vars are set the keys stay byte-identical
to legacy keys, so single-account setups keep their cache warm.

Fixes slkiser#235
…cache

# Conflicts:
#	tests/lib.google-token-cache.test.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: quota disk cache is shared across accounts — multi-instance setups show the wrong account's quotas

2 participants