fix(workspace-provision, RC 12082): provider-aware BYOK credential presence gate #3180
Reference in New Issue
Block a user
Delete Branch "fix/rc12082-provision-time-provider-aware"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Fixes the provision-time branch of RC 12082: the BYOK credential presence check (
hasAnyPlatformManagedLLMKey) was using the GLOBALplatformManagedDirectLLMBypassKeysset as a presence proxy, regardless of the resolved provider. A claude-code+anthropic workspace with onlyOPENAI_API_KEYwould satisfy presence (the key IS in the global set), then 201+credential-less+die-at-provision.The fix: intersect the bypass-set iteration with the resolved provider's
auth_env. A present key is now presence only if (a) it's in the global bypass shape AND (b) it's in the resolved provider'sauth_env. The global set is a cheap pre-filter; the provider-match is the real fail-closed check.Why this is the right scope (per PM ede6ecde)
The original #2328 PR (
566b5adf, 8 days stale, 1389 commits behind main) carried the create-time-gate provider-mismatch fix. PM decided not to cherry-pick the stale-feature fix; instead, fix the equivalent provider-mismatch hole in the provision-time gate that's on current main — the live-incident path, independently buildable. This PR does exactly that.Changes
workspace-server/internal/handlers/workspace_provision.go:hasAnyPlatformManagedLLMKeynow takes aproviders.Providerand intersects the bypass-set iteration withprovider.AuthEnv(mirrorsanyBYOKCredentialKeyMatchesProviderinbyok_credential_gate.go).applyPlatformManagedLLMEnvderives the resolved provider fromruntime/model(orres.ProviderSelection) BEFORE the presence check, so the provider is always available. Registry unavailable → defaults to the zero-value Provider (emptyAuthEnv) which fails presence (safe default — a misconfigured registry cannot accidentally satisfy a byok workspace's credential check).workspace-server/internal/handlers/byok_provision_provider_mismatch_test.go(NEW). 5 regression tests:TestHasAnyPlatformManagedLLMKey_ProviderMismatch_FailsClosed— the RC 12082 root case: claude-code+anthropic with onlyOPENAI_API_KEYreturnsfalse(wastruepre-fix).TestHasAnyPlatformManagedLLMKey_ProviderMatch_Passes— positive case:ANTHROPIC_API_KEY+ anthropic-api returnstrue.TestHasAnyPlatformManagedLLMKey_OpenAI_OK— symmetry:OPENAI_API_KEY+ openai returnstrue.TestHasAnyPlatformManagedLLMKey_EmptyEnvVars— empty envVars returnsfalse(preserves the pre-fix behavior).TestHasAnyPlatformManagedLLMKey_EmptyAuthEnv— provider with emptyauth_envreturnsfalse(registry-misconfig safety).Tests
All handler tests pass locally:
Out of scope (covered by separate work per PM's queue plan)
anyBYOKCredentialKeyMatchesProvider. The original #2328 PR (566b5adf) was the build for that fix; it was deferred per PM ede6ecde. A follow-up PR for the create-time fix can land independently.61aa8ca1(vacuous test fixes).Gate (per PM)
APPROVED on head
d5f6d368.Security/provisioner 5-axis review:
applyPlatformManagedLLMEnvderives the effective model, uses the resolver/registry to identify the BYOK provider, and passes that provider intohasAnyPlatformManagedLLMKey; presence now requires recognized LLM key shape + providerAuthEnvmatch + non-empty value.AuthEnvall produce an empty provider/auth set, so presence is false and the MISSING_BYOK_CREDENTIAL branch can fire instead of allowing a credential-less start.OPENAI_API_KEYalone no longer satisfies an anthropic-resolved claude-code workspace. The check mirrors the create-time provider-aware BYOK gate.AuthEnv. Reverting to the old global-bypass-only predicate would fail the root-case and empty-AuthEnv tests.APPROVE core#3180 @d5f6d368.
Five-axis review:
applyPlatformManagedLLMEnvresolves the effective provider before returning the BYOK result, andhasAnyPlatformManagedLLMKeyrequires all three conditions: known platform-managed LLM key shape, non-empty env value, and membership in the resolved provider'sAuthEnv.OPENAI_API_KEYnow returns false, whereas the old global-bypass-only predicate would have returned true. Positive Anthropic/OpenAI cases prevent blanket false rejection. Empty env and empty provider auth-env both fail closed.HasUsableLLMCred=falseon the BYOK provision path, causing the existingMISSING_BYOK_CREDENTIALabort instead of starting credential-less. No secret values are logged or newly exposed.go, but live Gitea shows the relevant Handlers Postgres Integration context green; broader CI was still pending/running at review time.No blocking findings. Scope noted: create-time gate remains deferred as stated; this approval is for the provision-time RC 12082 fix.