Skip to content

fix(ui): surface env-var-sourced theme and logging-callback settings - #34156

Merged
yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
litellm_env_settings_theme_callbacks
Jul 22, 2026
Merged

fix(ui): surface env-var-sourced theme and logging-callback settings#34156
yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
litellm_env_settings_theme_callbacks

Conversation

@yassin-berriai

@yassin-berriai yassin-berriai commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

Linear ticket

Resolves LIT-4667

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

Follow-up to #33576, which fixed the same env-blindness for SSO and SMTP and left the remaining read endpoints as separate tickets. These two endpoints are pure config readers with no LLM call, so the proof is a before/after curl of the effective config on one proxy configured the way an IaC shop configures one: UI theme and logging-callback settings supplied only as process env vars, nothing ever written through the UI.

export UI_LOGO_PATH="https://cdn.example.com/lit4667-logo.png"
export LITELLM_FAVICON_URL="https://cdn.example.com/lit4667-favicon.ico"
export LANGFUSE_PUBLIC_KEY="pk-lf-lit4667-public"
export LANGFUSE_SECRET_KEY="sk-lf-lit4667-secret"
export LANGFUSE_HOST="https://cloud.langfuse.com"
# config.yaml carries success_callback: ["langfuse"] and a master key, nothing else

python litellm/proxy/proxy_cli.py --config config.yaml --port 4667 --detailed_debug

Before, at 257ada88cc

Both features are live from the environment, yet the two endpoints the Admin UI reads report everything as unset

$ curl -s http://127.0.0.1:4667/get/ui_theme_settings | jq .values
  logo_url  = None
  favicon   = None

$ curl -s -H "Authorization: Bearer sk-envset-4667" http://127.0.0.1:4667/get/config/callbacks
  langfuse variables:
    LANGFUSE_PUBLIC_KEY = null
    LANGFUSE_SECRET_KEY = null
    LANGFUSE_HOST       = null

logo_url being null renders the theme settings page as an empty-state placeholder, and every Langfuse field reading null makes a working callback look unconfigured, which is what the customer's leadership sees when they evaluate the gateway through the UI.

After, at 08fc9c2122

Same commands, same environment

$ curl -s http://127.0.0.1:4667/get/ui_theme_settings | jq .values
  logo_url  = 'https://cdn.example.com/lit4667-logo.png'
  favicon   = 'https://cdn.example.com/lit4667-favicon.ico'

$ curl -s -H "Authorization: Bearer sk-envset-4667" http://127.0.0.1:4667/get/config/callbacks
  langfuse variables:
    LANGFUSE_PUBLIC_KEY = 'pk-lf-lit4667-public'
    LANGFUSE_SECRET_KEY = 'sk-lf-lit4667-secret'
    LANGFUSE_HOST       = 'https://cloud.langfuse.com'

The callback response above is for a full admin (master key). Secret callback values stay redacted for anyone below full admin exactly as before, since the fix only changes where the value is resolved from, not the role gate that masks it. test_get_config_callback_env_secrets_redacted_for_non_admin pins that: an env-only LANGFUSE_SECRET_KEY comes back as REDACTED for an internal user while the non-secret LANGFUSE_HOST still resolves. Only full admins can save config, and they see the plaintext, so there is no mask for a resubmit to persist over the real value.

Admin UI

The same env-only gateway in the dashboard. UI Theme reflects the logo and favicon supplied via UI_LOGO_PATH / LITELLM_FAVICON_URL, and Logging & Alerts lists the env-configured Langfuse callback

UI Theme settings populated from UI_LOGO_PATH and LITELLM_FAVICON_URL

Logging and Alerts showing the env-configured Langfuse callback

Type

🐛 Bug Fix

Changes

The UI theme and logging-callback read endpoints reported only stored config while the features themselves resolve their values from the process environment, so a gateway configured purely through env vars showed blank settings pages even though branding rendered and callbacks fired.

/get/ui_theme_settings read only litellm_settings.ui_theme_config. The update path writes logo_url/favicon_url there and to UI_LOGO_PATH/LITELLM_FAVICON_URL, so a deployment that sets only those env vars has no stored row and read blank. logo_url and favicon_url now fall back to those env vars when the stored config leaves them blank, with the stored value still winning so the UI-driven flow is unchanged

process_callback, which builds the logging-callbacks block of /get/config/callbacks, read each callback env var from the config environment_variables overlay and reported None when absent, never falling back to os.getenv. The slack block in the same handler already fell back to the environment; the callback block did not. It now goes through the same fallback, so a callback configured via env vars reports its live values

Secret callback values continue to be redacted for non-admins by the existing callback role gate, and full admins continue to see them in plaintext as they did for stored config, so no new class of value is exposed to any role

QA runbook

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai

@greptile-apps

greptile-apps Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes the Admin UI reflect theme and callback settings supplied through process environment variables. The main changes are:

  • Falls back to UI_LOGO_PATH and LITELLM_FAVICON_URL for missing stored theme values
  • Withholds env-sourced local paths from the public theme settings response
  • Falls back to process environment values for callback configuration
  • Preserves stored-value precedence and callback secret redaction
  • Adds focused tests for fallback, precedence, filtering, and redaction

Confidence Score: 5/5

This looks safe to merge.

  • The public theme response now filters env-sourced local paths.
  • Stored theme values still take precedence over environment values.
  • Callback secrets remain protected by the existing role-based redaction.
  • Tests cover the updated fallback and filtering behavior.

Important Files Changed

Filename Overview
litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py Adds theme environment fallback and filters env-derived values before returning them publicly.
litellm/proxy/common_utils/callback_utils.py Falls back to process environment values when callback variables are absent from stored configuration.
tests/test_litellm/proxy/ui_crud_endpoints/test_proxy_setting_endpoints.py Tests theme fallback, stored-value precedence, missing values, and local-path filtering.
tests/test_litellm/proxy/test_proxy_server.py Tests callback environment fallback and secret redaction for non-admin users.
tests/test_litellm/proxy/common_utils/test_callback_utils.py Tests callback fallback, stored-value precedence, and absent variables.

Reviews (3): Last reviewed commit: "fix(ui): surface env-var-sourced theme a..." | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes UI configuration readers reflect settings supplied through process environment variables. The main changes are:

  • Environment fallback for logging callback variables
  • Environment fallback for UI logo and favicon settings
  • Tests for precedence, missing values, and non-admin secret redaction

Confidence Score: 4/5

The public theme-settings response needs to filter local filesystem paths before merging.

  • Callback values use the existing role-based secret redaction.
  • Stored configuration still takes precedence over environment values.
  • Local branding paths can now be returned to unauthenticated callers.

litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py

Security Review

Callback secrets remain protected by the existing role-based redaction. The public theme-settings endpoint can now disclose local filesystem paths from branding environment variables.

Important Files Changed

Filename Overview
litellm/proxy/common_utils/callback_utils.py Adds process-environment fallback for callback variables while preserving stored-value precedence.
litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py Adds theme environment fallback but can expose local branding paths through a public endpoint.
tests/test_litellm/proxy/common_utils/test_callback_utils.py Tests callback environment fallback, stored precedence, and missing values.
tests/test_litellm/proxy/test_proxy_server.py Tests callback endpoint fallback and secret redaction for non-admin users.
tests/test_litellm/proxy/ui_crud_endpoints/test_proxy_setting_endpoints.py Tests theme fallback and precedence but does not cover local-path environment values.

Reviews (2): Last reviewed commit: "fix(ui): surface env-var-sourced theme a..." | Re-trigger Greptile

Comment thread litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py Outdated
Comment thread litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py Outdated
@veria-ai

veria-ai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 1 · PR risk: 0/10

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_env_settings_theme_callbacks (3b7de84) with litellm_internal_staging (2b2ae4c)

Open in CodSpeed

The UI theme and logging-callback read endpoints reported only stored
config while the features resolve their values from the process
environment, so a gateway configured purely through env vars showed
blank settings pages even though branding rendered and callbacks fired.

/get/ui_theme_settings read only litellm_settings.ui_theme_config;
logo_url and favicon_url now fall back to UI_LOGO_PATH and
LITELLM_FAVICON_URL when the stored config leaves them blank.

process_callback (the logging-callbacks block of /get/config/callbacks)
reported every callback env var as unset unless it lived in the config
environment_variables overlay; it now falls back to os.getenv, matching
the slack block. Secret values stay redacted for non-admins via the
existing callback role gate.

Stored values keep winning over the environment, so the UI-driven flow
is unchanged.

Resolves LIT-4667
@yassin-berriai
yassin-berriai force-pushed the litellm_env_settings_theme_callbacks branch from 08fc9c2 to 3b7de84 Compare July 21, 2026 22:41
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

Addressed the Veria finding (Low: local branding path disclosure). /get/ui_theme_settings is unauthenticated, so the env fallback now only surfaces a public http(s) URL: an operator can point UI_LOGO_PATH at a local filesystem path (the branding path still serves it server-side), and that path is no longer disclosed to anonymous callers. A stored value is already validated as a public URL on write, so it passes through. Added a regression test.

@greptileai please review the current head 3b7de84

@yassin-berriai
yassin-berriai merged commit 1aba849 into litellm_internal_staging Jul 22, 2026
79 of 80 checks passed
@yassin-berriai
yassin-berriai deleted the litellm_env_settings_theme_callbacks branch July 22, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants