From 7e4d1ffc290ec7f6f6748bd2f068e762a3544e44 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Apr 2026 06:14:25 -0500 Subject: [PATCH] scrum: validate API key presence when enabling cloud provider admin_save_config silently accepted enabled=True for any provider even when no api_key was configured (neither in the request body, nor already stored, nor available in the provider's env var). Result: /api/admin/config returned 200, the provider was marked enabled in UI and config, then every actual query to that provider 401'd at call time with an opaque error. The fix: when the incoming patch sets enabled=True, compute the effective key (request body preferred, falling back to stored config, falling back to the provider's env var via get_api_key()) and reject with 400 if the effective key is empty. Keeps all existing behavior for disabled providers and for updates that don't touch enabled. Surfaced by lakehouse scrum-master pipeline run 2026-04-24 (finding F5). --- llm_team_ui.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/llm_team_ui.py b/llm_team_ui.py index f1bf4db..61d3d0a 100644 --- a/llm_team_ui.py +++ b/llm_team_ui.py @@ -7064,6 +7064,18 @@ def admin_save_config(): new_key = prov.get("api_key", "") if not new_key: prov["api_key"] = cfg["providers"][name].get("api_key", "") + # Enabling a cloud provider requires a usable key (incoming, + # stored, or env). Prevents silent auth failures where + # `enabled=True` is saved with no key and queries 401 at + # call time. get_api_key() checks config + env fallback. + if prov.get("enabled") is True: + effective_key = prov.get("api_key") or get_api_key(name) + if not effective_key: + return jsonify({ + "error": f"Cannot enable provider '{name}' without an API key. " + f"Provide api_key in the request, save a key first, " + f"or set the environment variable." + }), 400 cfg["providers"][name].update(prov) if "disabled_models" in data: cfg["disabled_models"] = data["disabled_models"]