fix(security): derive <VENDOR>_API_KEY from host as final credential fallback

After #28660's host-gating fix, users with provider=custom and base_url
pointed at a commercial endpoint (DeepSeek, Groq, Mistral, …) hit
no-key-required even when they had the vendor-named env var set
(DEEPSEEK_API_KEY, GROQ_API_KEY, …). The issue author flagged this as
'what users intuitively expect'.

Adds _host_derived_api_key() to derive an env var name from the base URL
host using the *registrable* label (second-to-last). Appended to all three
api_key_candidates chains (_resolve_named_custom_runtime direct-alias path,
named-custom path, _resolve_openrouter_runtime non-openrouter branch).

Lookalike resistance: api.deepseek.com.attacker.test resolves to vendor
label 'attacker', NOT 'deepseek' — DEEPSEEK_API_KEY stays put. IPs and
loopback yield no vendor label. Already-handled vendors (OPENAI/OPENROUTER/
OLLAMA) are filtered to prevent bypass of the explicit host-gated paths.

Adds 6 tests covering positive paths (DeepSeek, Groq), the lookalike attack,
loopback rejection, the already-handled-vendor filter, and direct helper
unit tests.

Also adds erhnysr to AUTHOR_MAP.
This commit is contained in:
Teknium 2026-05-20 20:05:50 -07:00
parent 9514ddbee2
commit c6a992e3e3
3 changed files with 230 additions and 0 deletions

View file

@ -47,6 +47,7 @@ ACP_REGISTRY_MANIFEST = REPO_ROOT / "acp_registry" / "agent.json"
AUTHOR_MAP = {
# teknium (multiple emails)
"teknium1@gmail.com": "teknium1",
"erhanyasarx@gmail.com": "erhnysr",
"30366221+WorldWriter@users.noreply.github.com": "WorldWriter",
"dafeng@DafengdeMacBook-Pro.local": "WorldWriter",
"anadi.jaggia@gmail.com": "Jaggia",