fix(qwen): one credential rule for both paths — seven findings said so
Fourteen findings, and seven of them from all four models are the same one: endpointProvider was missing the no-cross-vendor-fallback guard I had just added to resolveModel. I fixed a credential leak on one path and left its sibling leaking, in the commit whose own message argued those two paths must move together. That is the third time in this PR. So it is no longer a rule written twice. openAICompatOptions owns it and both paths call it; builtinCompatProviders names the vendors that must never inherit OPENAI_API_KEY, replacing a `provider == "kimi" || provider == "qwen"` literal that was a fourth uncounted copy of the list. The test drives a real request at a local server and demands two things: that no request arrives carrying the OpenAI key, AND that the call fails closed naming the variable to set — the second half because my first draft pointed the provider at vendor.example, so the server saw nothing and the assertion held for a reason unrelated to the fix. Break-checked: removing the guard puts "Bearer sk-openai-must-not-travel" on the wire to the other vendor. The scrub check failed open. As a bare condition, a grep ERROR (exit >= 2) reads as "not found" and skips the guard — a credential check that passes precisely when it cannot see the filesystem it is searching. It now distinguishes 0/1/>=2 and refuses to continue on error. A bare "claude-code" spec has no "/", so the provider fell back to ollama-cloud and the pre-flight would skip a reviewer that authenticates with CLAUDE_CODE_OAUTH_TOKEN and needs no Ollama key. Engine specs are now exempt. preflight.sh's provider list duplicated its own case arms; both now read one table. And its comment claimed the Go cross-check fails if either list misses an entry from the other, when only one direction is checked — the reverse is not even desirable, since ollama-cloud and anthropic belong in that table and not in the Go one. The comment now says what is enforced. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -108,12 +108,21 @@ jobs:
|
||||
# write ~/.netrc or ~/.config/go/env. Guarded on a non-empty secret:
|
||||
# `grep -F ""` matches every file, so a secretless run (fork PR) would
|
||||
# fail here with a message accusing it of leaking nothing.
|
||||
# -e, so a password beginning with "-" is a pattern and not options:
|
||||
# without it the check errors out and, under `set -e`, fails the step
|
||||
# with a message about grep usage rather than about credentials.
|
||||
if [ -n "${REGISTRY_PASSWORD:-}" ] && grep -rqF -e "$REGISTRY_PASSWORD" "$HOME" 2>/dev/null; then
|
||||
echo "::error::registry credential still present under \$HOME after scrub"
|
||||
exit 1
|
||||
# -e, so a password beginning with "-" is a pattern and not options.
|
||||
# And distinguish grep's three exits: 0 found, 1 clean, >=2 ERROR. As
|
||||
# a bare condition an error reads as "not found" and the guard is
|
||||
# skipped — a check that fails OPEN in exactly the case where it can no
|
||||
# longer see the filesystem it is supposed to be searching.
|
||||
if [ -n "${REGISTRY_PASSWORD:-}" ]; then
|
||||
set +e
|
||||
grep -rqF -e "$REGISTRY_PASSWORD" "$HOME" 2>/dev/null
|
||||
rc=$?
|
||||
set -e
|
||||
case "$rc" in
|
||||
0) echo "::error::registry credential still present under \$HOME after scrub"; exit 1 ;;
|
||||
1) : ;; # clean
|
||||
*) echo "::error::credential scrub check could not run (grep exit $rc); refusing to continue"; exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# GOPROXY=off from here on: the module cache is already warm, so any
|
||||
|
||||
Reference in New Issue
Block a user