litellm/litellm/proxy/common_utils
yuneng-jiang 666f6b01b4
fix: enforce disable_custom_api_keys from general_settings (#42437)
* fix: enforce disable_custom_api_keys from general_settings

The gate in _check_custom_key_allowed read the persisted UI settings row
through get_ui_settings_cached, which had two consequences.

A config-file general_settings.disable_custom_api_keys was never enforced,
because the gate only ever looked at the stored ui_settings row. POST
/key/generate with a custom key value returned 200 even with the flag set
to true in config.yaml.

The read went through a DualCache with a 600s TTL, which is per worker
without Redis, and only the worker that served PATCH /update/ui_settings
refreshed it. A gate flipped through the UI was then a coin flip across
workers for up to ten minutes.

Both go away by routing the flag the way the other runtime UI flags are
already routed. Adding it to _RUNTIME_GENERAL_SETTINGS_FLAGS and to the
settings rules' _UI_SETTINGS_FIELDS makes SettingsStore resolve it from the
ui_settings row with the config file winning, and every pod re-reads it on
its own settings sync rather than holding a private cached copy. The two
lists have to stay in step: a flag in one and not the other resolves
against the wrong stored row and silently never reaches a reader, so there
is a test for that invariant.

Writes to the ui_settings table did not publish on the config-sync channel,
so other pods only discovered a change on their next periodic reload. Adding
litellm_uisettings to _CONFIG_SYNCED_TABLE_NAMES puts it on the same pubsub
path model and SSO config writes already use, which cuts cross-pod
propagation from tens of seconds to a few.

The value reaching the gate is run through coerce_bool first. Resolution
hands back the raw YAML value, so a quoted "true" in config.yaml is a str
and the old `is True` check let custom keys straight through.

* test: assert both directions of the coerced config value

* test: assert the runtime flags read back instead of inspecting the registry
2026-09-22 13:28:31 -07:00
..
html_forms fix(proxy): move credentials hint helper into a leaf html_forms module to clear CodeQL cyclic import 2026-09-14 20:34:58 +00:00
admin_ui_utils.py docs: stop advertising sk-1234 as the master key in shipped configs and examples 2026-09-19 12:59:48 -07:00
auth_cache_invalidation_pubsub.py fix(proxy): give user-key objects their own in-memory cache partition (#40713) 2026-09-11 09:52:09 -07:00
banner.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
cache_coordinator.py refactor(typing): replace Any with proven types in 65 backend files 2026-09-02 09:11:36 +00:00
cache_pydantic_utils.py refactor(types): replace Any with real types across 54 more backend files 2026-09-08 12:41:07 +00:00
callback_config_validation.py feat(arize): per-team success and error sampling rates for the Arize AX callback (#42383) 2026-09-22 11:21:40 -05:00
callback_utils.py Merge remote-tracking branch 'origin/main' into litellm_decrease_anys_opus5_r5 2026-09-21 12:57:38 -07:00
config_includes.py fix(proxy): make an ambiguous config include loud, not silent 2026-09-06 03:35:07 -07:00
config_sync_pubsub.py fix: enforce disable_custom_api_keys from general_settings (#42437) 2026-09-22 13:28:31 -07:00
custom_openapi_spec.py refactor(types): replace Any with real types across 54 more backend files 2026-08-29 19:00:43 +00:00
debug_utils.py feat(proxy): admin-only /debug/report sharing the bug report environment (#42440) 2026-09-22 12:05:23 -07:00
encrypt_decrypt_utils.py fix(proxy): never treat plaintext that base64-decodes to nothing as a ciphertext during the master key migration 2026-09-19 17:53:17 -07:00
error_body_call_id.py feat(proxy): opt-in litellm_call_id in JSON error bodies (#42391) 2026-09-21 19:17:18 -07:00
expired_ui_session_key_cleanup_manager.py refactor(repositories): type prisma table access with one generic protocol 2026-08-25 12:14:17 +00:00
get_routes.py refactor(types): replace Any with real types across 178 backend files 2026-08-27 10:14:58 +00:00
healthy_model_filter.py feat(proxy): hide unhealthy models from model listings, opt-in 2026-08-26 00:13:52 -07:00
http_parsing_utils.py Merge remote-tracking branch 'origin/main' into litellm_decrease_anys_opus5_r5 2026-09-21 12:57:38 -07:00
json_merge_patch.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
key_rotation_manager.py refactor(repositories): type prisma table access with one generic protocol 2026-08-25 12:14:17 +00:00
load_config_utils.py fix(proxy): make an ambiguous config include loud, not silent 2026-09-06 03:35:07 -07:00
model_deprecation.py fix(proxy): escape slack markup in model deprecation alert fields 2026-08-13 02:39:34 +00:00
model_listing_utils.py feat(proxy): expose reversible Claude Code model listing aliases (#40515) 2026-09-09 22:04:37 -07:00
openai_endpoint_utils.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
openai_error_payload.py fix(proxy): build failure headers immutably to keep LIT002 within budget 2026-09-16 18:51:22 +00:00
openapi_schema_compat.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
path_utils.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
periodic_reload_schedule.py fix(proxy): persist periodic reload schedule state so status survives restarts and fires without store_model_in_db (#35165) 2026-08-04 15:42:57 -07:00
prompt_cache_pricing.py feat(proxy): predict prompt-cache costs across deployments 2026-09-12 14:02:45 -07:00
proxy_rate_limit_error.py Merge remote-tracking branch 'origin/main' into litellm_decrease_anys_opus5_r5 2026-09-21 12:57:38 -07:00
proxy_state.py (feat) UI - Disable Usage Tab once SpendLogs is 1M+ Rows (#7208) 2024-12-12 18:43:17 -08:00
rbac_utils.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
realtime_utils.py refactor(lint): apply every safe ruff autofix and zero 28 strict-rule budgets 2026-08-01 15:43:29 -07:00
registry_read_through.py fix(proxy): load db credentials in the model reconcile so a worker never serves a model before its credential (#39876) 2026-09-08 10:08:24 -07:00
reset_budget_job.py Merge remote-tracking branch 'origin/main' into litellm_decrease_anys_opus5_r5 2026-09-21 12:57:38 -07:00
resource_ownership.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
responses_stream_errors.py refactor(responses): map status codes to error codes with a lookup 2026-09-18 14:57:15 -07:00
scheduled_job_stagger.py perf(proxy): stagger scheduled background jobs across jobs and pods (#36589) 2026-08-12 09:17:31 -07:00
semantic_text_index.py feat(skills): semantic search over the LiteLLM-hosted skill registry (#39401) 2026-09-07 12:28:38 -07:00
sse_keepalive.py fix(passthrough): recognize CR-only SSE frame delimiters when minting streamed managed ids 2026-08-26 01:36:18 -07:00
static_asset_utils.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
swagger_utils.py fix(proxy): make the lazy OpenAPI snapshot byte-identical on every Python version (#42519) 2026-09-22 12:21:20 -07:00
timezone_utils.py fix(management_v1): authorize bulk member budget writes off the writer and reject unschedulable reset windows 2026-09-17 13:31:32 -07:00
user_api_key_cache.py Merge remote-tracking branch 'origin/main' into litellm_lit_3269_project_spend_tracking 2026-09-17 22:29:16 +00:00