You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The active model listing path combines three caches: a 60-second in-memory adapter/auth snapshot, a 24-hour persisted API model catalog, and runtime-specific local catalogs. The API path is not consistently bound to one credential.
ProbeAdapters accepts caller-supplied APICredentials and reports auth from that snapshot, but fetchAPIModels uses the snapshot only to decide that a key exists. ResolveModels then re-reads the process vault/environment for fingerprinting and re-reads it again while fetching. A caller can therefore receive auth status for token/account B with model availability fetched under token/account A. Token rotation during one probe creates the same time-of-check/time-of-use mismatch.
The persisted catalog is also a single models.json slot while authenticated backends resolve concurrently. Every backend writes the same models.json.tmp path, so multiple configured API tokens race and only one backend remains cached. The outer adapter cache is timestamp-only, leaving changed or removed tokens and local login methods stale for up to 60 seconds.
Scope
Carry one immutable resolved credential snapshot through auth reporting, cache fingerprinting, and the provider model-list request. Never re-resolve a global credential during the same operation.
Ensure ProbeAdapters uses the exact credential supplied in AuthProbe, including custom callers and tests.
Partition persisted API model availability by backend, provider endpoint, resolution options/schema version, and a non-secret namespace for the exact effective token or account.
Treat vault and environment source changes with the same effective token consistently, while always separating different tokens and API versus CLI/OAuth auth.
Keep CLI/local-runtime catalogs separate from API-key-gated model lists. Where a local catalog is account-specific, include a stable account namespace or do not persist it.
Replace the single cache slot and shared temporary filename with concurrency-safe per-key entries or one locked multi-entry document using unique temporary files.
Invalidate availability immediately when the effective token, login account, endpoint, or credential presence changes; do not rely solely on the 60-second TTL.
Do not derive or persist fingerprints for unrelated provider tokens, or for catalog-only queries with token use disabled.
Store model rows and any credential verifier under 0700/0600 permissions. Use a machine-local keyed HMAC rather than a fixed-salt, low-cost token verifier, and never persist or log raw credentials.
Preserve an explicit refresh path without allowing refreshes for one backend to evict another backend cache entry.
Security cases
A caller-supplied token must be the exact token used for the live model request and its cache namespace.
Token A model availability must never be returned as token B availability.
Removing a token or changing a local login must immediately change readiness and availability.
Multiple simultaneously configured provider tokens must retain independent 24-hour cache entries without write races.
Private, restricted, or fine-tuned model IDs must not be exposed to other local users.
Non-goals
Generated provider output caching is tracked separately.
One resolved credential snapshot drives adapter auth status, cache identity, and the live model-list request.
ProbeAdapters uses caller-supplied APICredentials rather than silently substituting process-global vault or environment credentials.
Different API tokens, provider endpoints, and API versus CLI/OAuth auth have isolated availability entries.
Vault and environment sources with the same effective token behave consistently without persisting the raw token.
Token rotation, token removal, and local account changes invalidate readiness and model availability without waiting for the outer TTL.
Concurrent resolution for at least two authenticated API backends retains correct independent cache entries and has no shared temporary-file race.
A warm cache avoids new provider model-list requests for every cached backend, not only the last writer.
Catalog-only resolution with token use disabled persists no credential-derived verifier.
Cache files and directories use 0600 and 0700 permissions respectively, and credential fingerprints use a machine-local keyed HMAC.
Raw tokens and reusable credential material are absent from persisted data and logs.
Focused credential-substitution, rotation, multi-backend concurrency, invalidation, and permissions tests fail against the old implementation and pass with the fix.
Problem
The active model listing path combines three caches: a 60-second in-memory adapter/auth snapshot, a 24-hour persisted API model catalog, and runtime-specific local catalogs. The API path is not consistently bound to one credential.
ProbeAdapters accepts caller-supplied APICredentials and reports auth from that snapshot, but fetchAPIModels uses the snapshot only to decide that a key exists. ResolveModels then re-reads the process vault/environment for fingerprinting and re-reads it again while fetching. A caller can therefore receive auth status for token/account B with model availability fetched under token/account A. Token rotation during one probe creates the same time-of-check/time-of-use mismatch.
The persisted catalog is also a single models.json slot while authenticated backends resolve concurrently. Every backend writes the same models.json.tmp path, so multiple configured API tokens race and only one backend remains cached. The outer adapter cache is timestamp-only, leaving changed or removed tokens and local login methods stale for up to 60 seconds.
Scope
Security cases
Non-goals
Generated provider output caching is tracked separately.
Verification
cwd: .
timeout: 15m
codeBlocks: [test, lint]
ai: {}
verify:
scope: diff
threshold: 100
Focused tests
Changed-code lint
Acceptance Criteria