From f61e05131f7ce0087f7dfe12859836ecc4d4b314 Mon Sep 17 00:00:00 2001
From: Nikolas Garza <90273783+nmgarza5@users.noreply.github.com>
Date: Thu, 24 Sep 2026 21:20:41 +0000
Subject: [PATCH] fix(enterprise-settings): remove the Hide Onyx Branding
toggle (#15112)
---
.../ee/onyx/server/enterprise_settings/api.py | 11 +----
.../onyx/server/enterprise_settings/models.py | 3 --
backend/onyx/configs/app_configs.py | 4 ++
backend/onyx/server/settings/api.py | 8 ++++
backend/onyx/server/settings/models.py | 2 +
.../test_enterprise_settings_store.py | 24 ++++++++++
.../docker_compose/docker-compose.prod.yml | 2 -
.../docker_compose/docker-compose.yml | 2 -
.../embedded/docker_compose/env.template | 3 +-
.../docker-compose.prod-no-letsencrypt.yml | 2 -
.../docker_compose/docker-compose.prod.yml | 2 -
.../docker-compose.search-testing.yml | 2 -
.../docker-compose.template.yml | 2 -
deployment/docker_compose/docker-compose.yml | 2 -
deployment/docker_compose/env.template | 3 +-
web/Dockerfile | 6 ---
.../admin/theme/AppearanceThemeSettings.tsx | 30 -------------
web/src/app/ee/admin/theme/page.tsx | 3 --
web/src/i18n/messages/ar.json | 5 ---
web/src/i18n/messages/de.json | 5 ---
web/src/i18n/messages/en.json | 5 ---
web/src/i18n/messages/es.json | 5 ---
web/src/i18n/messages/fr.json | 5 ---
web/src/i18n/messages/ja.json | 5 ---
web/src/i18n/messages/ko.json | 5 ---
web/src/i18n/messages/pt.json | 5 ---
web/src/i18n/messages/zh.json | 5 ---
web/src/lib/app/components.tsx | 29 ++++++------
web/src/lib/constants.ts | 4 --
web/src/lib/settings/types.ts | 6 +--
.../e2e/admin/theme/AppearanceThemePage.ts | 30 ++-----------
.../theme/appearance_theme_settings.spec.ts | 44 +++++--------------
32 files changed, 75 insertions(+), 194 deletions(-)
create mode 100644 backend/tests/unit/ee/onyx/server/enterprise_settings/test_enterprise_settings_store.py
diff --git a/backend/ee/onyx/server/enterprise_settings/api.py b/backend/ee/onyx/server/enterprise_settings/api.py
index a067aed84a..a2938ae7f4 100644
--- a/backend/ee/onyx/server/enterprise_settings/api.py
+++ b/backend/ee/onyx/server/enterprise_settings/api.py
@@ -200,10 +200,8 @@ def admin_ee_put_settings(
settings: EnterpriseSettings,
_: User = Depends(require_permission(Permission.FULL_ADMIN_PANEL_ACCESS)),
) -> None:
- # Custom help link and Onyx-branding toggle are Enterprise-only. Block
- # writes to those fields when tier < ENTERPRISE so the FE disabled state
- # cannot be bypassed by crafting a request. Uses FEATURE_NOT_AVAILABLE
- # (402) to match the tier_gate middleware shape.
+ # Custom help link is Enterprise-only. Enforced here so a crafted request
+ # cannot bypass the disabled field in the UI.
if not tier_at_least(get_tier(), Tier.ENTERPRISE):
existing = load_settings()
if (
@@ -214,11 +212,6 @@ def admin_ee_put_settings(
OnyxErrorCode.FEATURE_NOT_AVAILABLE,
"Custom help link requires the Enterprise plan.",
)
- if settings.hide_onyx_branding != existing.hide_onyx_branding:
- raise OnyxError(
- OnyxErrorCode.FEATURE_NOT_AVAILABLE,
- "Hiding Onyx branding requires the Enterprise plan.",
- )
store_settings(settings)
diff --git a/backend/ee/onyx/server/enterprise_settings/models.py b/backend/ee/onyx/server/enterprise_settings/models.py
index 68c4d0d0c4..8b739e7519 100644
--- a/backend/ee/onyx/server/enterprise_settings/models.py
+++ b/backend/ee/onyx/server/enterprise_settings/models.py
@@ -111,9 +111,6 @@ class EnterpriseSettings(BaseModel):
custom_help_link_url: str | None = None
custom_help_link_label: str | None = None
- # hide the "Powered by Onyx" tagline under the sidebar logo
- hide_onyx_branding: bool | None = None
-
@field_validator("custom_help_link_url")
@classmethod
def _validate_help_link_scheme(cls, v: str | None) -> str | None:
diff --git a/backend/onyx/configs/app_configs.py b/backend/onyx/configs/app_configs.py
index e484d49c6c..9001b46e2c 100644
--- a/backend/onyx/configs/app_configs.py
+++ b/backend/onyx/configs/app_configs.py
@@ -79,6 +79,10 @@ DISABLE_USER_KNOWLEDGE = os.environ.get("DISABLE_USER_KNOWLEDGE", "").lower() ==
# are disabled but core chat, tools, user file uploads, and Projects still work.
DISABLE_VECTOR_DB = os.environ.get("DISABLE_VECTOR_DB", "").lower() == "true"
+# Hides the "Powered by Onyx" tagline on Enterprise deployments. Do not set
+# without explicit permission from Onyx.
+HIDE_ONYX_BRANDING = os.environ.get("HIDE_ONYX_BRANDING", "").lower() == "true"
+
# TEMPORARY (will be removed soon): operator-forced Search-UI scope (self-hosted only) —
# comma-separated document set NAMES. When set, the Onyx Search UI is restricted to those sets
# (AND'd on top of any persona/user scope; ACL still enforced) — chat/other flows are unaffected,
diff --git a/backend/onyx/server/settings/api.py b/backend/onyx/server/settings/api.py
index 5065e026d6..32875293bc 100644
--- a/backend/onyx/server/settings/api.py
+++ b/backend/onyx/server/settings/api.py
@@ -10,6 +10,7 @@ from onyx.auth.users import is_user_admin
from onyx.configs.app_configs import (
DEFAULT_USER_FILE_MAX_UPLOAD_SIZE_MB,
DISABLE_VECTOR_DB,
+ HIDE_ONYX_BRANDING,
MAX_ALLOWED_UPLOAD_SIZE_MB,
POSTHOG_API_KEY,
POSTHOG_HOST,
@@ -170,6 +171,11 @@ def fetch_settings(
apply_license_status_to_settings,
)
general_settings = apply_fn(general_settings)
+ # The EE apply_fn resolves tier on every path. On CE the stored value is
+ # client-writable, so it never counts.
+ resolved_tier = (
+ general_settings.tier if global_version.is_ee_version() else Tier.COMMUNITY
+ )
# Craft workspace instructions are visible to authenticated users (they
# appear in sandbox AGENTS.md anyway) but not to anonymous visitors.
@@ -202,6 +208,8 @@ def fetch_settings(
onyx_craft_available=onyx_craft_available,
opencode_debugging_enabled=ENABLE_OPENCODE_DEBUGGING,
vector_db_enabled=not DISABLE_VECTOR_DB,
+ hide_onyx_branding=HIDE_ONYX_BRANDING
+ and tier_at_least(resolved_tier, Tier.ENTERPRISE),
hooks_enabled=not MULTI_TENANT,
version=onyx_version,
max_allowed_upload_size_mb=MAX_ALLOWED_UPLOAD_SIZE_MB,
diff --git a/backend/onyx/server/settings/models.py b/backend/onyx/server/settings/models.py
index c597aefd5a..a11a69704e 100644
--- a/backend/onyx/server/settings/models.py
+++ b/backend/onyx/server/settings/models.py
@@ -128,6 +128,8 @@ class UserSettings(Settings):
# False when DISABLE_VECTOR_DB is set — connectors, RAG search, and
# document sets are unavailable.
vector_db_enabled: bool = True
+ # HIDE_ONYX_BRANDING env var, honored only on the Enterprise tier.
+ hide_onyx_branding: bool = False
# True when hooks are available: single-tenant EE deployments only.
hooks_enabled: bool = False
# Application version, read from the ONYX_VERSION env var at startup.
diff --git a/backend/tests/unit/ee/onyx/server/enterprise_settings/test_enterprise_settings_store.py b/backend/tests/unit/ee/onyx/server/enterprise_settings/test_enterprise_settings_store.py
new file mode 100644
index 0000000000..694e78c875
--- /dev/null
+++ b/backend/tests/unit/ee/onyx/server/enterprise_settings/test_enterprise_settings_store.py
@@ -0,0 +1,24 @@
+from unittest.mock import MagicMock, patch
+
+from ee.onyx.server.enterprise_settings.store import load_settings, store_settings
+
+
+def test_legacy_hide_onyx_branding_is_dropped_on_load_and_save() -> None:
+ kv_store = MagicMock()
+ kv_store.load.return_value = {
+ "application_name": "Acme",
+ "hide_onyx_branding": True,
+ }
+
+ with patch(
+ "ee.onyx.server.enterprise_settings.store.get_kv_store",
+ return_value=kv_store,
+ ):
+ settings = load_settings()
+ store_settings(settings)
+
+ assert settings.application_name == "Acme"
+ assert "hide_onyx_branding" not in settings.model_dump()
+ stored = kv_store.store.call_args.args[1]
+ assert "hide_onyx_branding" not in stored
+ assert stored["application_name"] == "Acme"
diff --git a/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.prod.yml b/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.prod.yml
index b603991f9a..baaad0de8d 100644
--- a/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.prod.yml
+++ b/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.prod.yml
@@ -167,8 +167,6 @@ services:
- NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=${NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED:-}
# Enterprise Edition only
- NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
- # DO NOT TURN ON unless you have EXPLICIT PERMISSION from Onyx.
- - NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED:-false}
- NODE_OPTIONS=${NODE_OPTIONS:-"--max-old-space-size=4096"}
env_file:
- path: .env
diff --git a/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.yml b/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.yml
index 87b608bbf4..756f76a657 100644
--- a/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.yml
+++ b/cli/internal/deploy/deployfiles/embedded/docker_compose/docker-compose.yml
@@ -208,8 +208,6 @@ services:
- NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=${NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED:-}
# Enterprise Edition only
- NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
- # DO NOT TURN ON unless you have EXPLICIT PERMISSION from Onyx.
- - NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED:-false}
- NODE_OPTIONS=${NODE_OPTIONS:-"--max-old-space-size=4096"}
env_file:
- path: .env
diff --git a/cli/internal/deploy/deployfiles/embedded/docker_compose/env.template b/cli/internal/deploy/deployfiles/embedded/docker_compose/env.template
index cc21d40a66..f785a819a6 100644
--- a/cli/internal/deploy/deployfiles/embedded/docker_compose/env.template
+++ b/cli/internal/deploy/deployfiles/embedded/docker_compose/env.template
@@ -409,6 +409,8 @@ LOG_ONYX_MODEL_INTERACTIONS=False
# SALESFORCE_CLIENT_SECRET=
## Miscellaneous
+# Hides "Powered by Onyx" on Enterprise. Do not set without explicit permission from Onyx.
+# HIDE_ONYX_BRANDING=
# Kill switch for the gateway's native Anthropic passthrough (server tools,
# thinking-block signatures, fine-grained streaming); default on. Set to false
# to send Anthropic-backed providers back through the OpenAI-translation path.
@@ -428,7 +430,6 @@ LOG_ONYX_MODEL_INTERACTIONS=False
# NEXT_PUBLIC_DISABLE_LOGOUT=
# NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=
# NEXT_PUBLIC_THEME=
-# NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=
# NEXT_PUBLIC_CUSTOM_REFRESH_URL=
## Pointer to services
diff --git a/deployment/docker_compose/docker-compose.prod-no-letsencrypt.yml b/deployment/docker_compose/docker-compose.prod-no-letsencrypt.yml
index bebc4eb3b6..e35b833f52 100644
--- a/deployment/docker_compose/docker-compose.prod-no-letsencrypt.yml
+++ b/deployment/docker_compose/docker-compose.prod-no-letsencrypt.yml
@@ -167,8 +167,6 @@ services:
- NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=${NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED:-}
# Enterprise Edition only
- NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
- # DO NOT TURN ON unless you have EXPLICIT PERMISSION from Onyx.
- - NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED:-false}
- NODE_OPTIONS=${NODE_OPTIONS:-"--max-old-space-size=4096"}
env_file:
- path: .env
diff --git a/deployment/docker_compose/docker-compose.prod.yml b/deployment/docker_compose/docker-compose.prod.yml
index b603991f9a..baaad0de8d 100644
--- a/deployment/docker_compose/docker-compose.prod.yml
+++ b/deployment/docker_compose/docker-compose.prod.yml
@@ -167,8 +167,6 @@ services:
- NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=${NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED:-}
# Enterprise Edition only
- NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
- # DO NOT TURN ON unless you have EXPLICIT PERMISSION from Onyx.
- - NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED:-false}
- NODE_OPTIONS=${NODE_OPTIONS:-"--max-old-space-size=4096"}
env_file:
- path: .env
diff --git a/deployment/docker_compose/docker-compose.search-testing.yml b/deployment/docker_compose/docker-compose.search-testing.yml
index cd30149e53..8fedc460e5 100644
--- a/deployment/docker_compose/docker-compose.search-testing.yml
+++ b/deployment/docker_compose/docker-compose.search-testing.yml
@@ -102,8 +102,6 @@ services:
# Enterprise Edition only
- NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
- # DO NOT TURN ON unless you have EXPLICIT PERMISSION from Onyx.
- - NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED:-false}
depends_on:
- api_server
restart: unless-stopped
diff --git a/deployment/docker_compose/docker-compose.template.yml b/deployment/docker_compose/docker-compose.template.yml
index 21aa5407e1..0ac8ded49b 100644
--- a/deployment/docker_compose/docker-compose.template.yml
+++ b/deployment/docker_compose/docker-compose.template.yml
@@ -251,8 +251,6 @@ services:
- NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=${NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED:-}
# Enterprise Edition only
- NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
- # DO NOT TURN ON unless you have EXPLICIT PERMISSION from Onyx.
- - NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED:-false}
- NODE_OPTIONS=${NODE_OPTIONS:-"--max-old-space-size=4096"}
env_file:
- path: .env
diff --git a/deployment/docker_compose/docker-compose.yml b/deployment/docker_compose/docker-compose.yml
index 87b608bbf4..756f76a657 100644
--- a/deployment/docker_compose/docker-compose.yml
+++ b/deployment/docker_compose/docker-compose.yml
@@ -208,8 +208,6 @@ services:
- NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=${NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED:-}
# Enterprise Edition only
- NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME:-}
- # DO NOT TURN ON unless you have EXPLICIT PERMISSION from Onyx.
- - NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED:-false}
- NODE_OPTIONS=${NODE_OPTIONS:-"--max-old-space-size=4096"}
env_file:
- path: .env
diff --git a/deployment/docker_compose/env.template b/deployment/docker_compose/env.template
index cc21d40a66..f785a819a6 100644
--- a/deployment/docker_compose/env.template
+++ b/deployment/docker_compose/env.template
@@ -409,6 +409,8 @@ LOG_ONYX_MODEL_INTERACTIONS=False
# SALESFORCE_CLIENT_SECRET=
## Miscellaneous
+# Hides "Powered by Onyx" on Enterprise. Do not set without explicit permission from Onyx.
+# HIDE_ONYX_BRANDING=
# Kill switch for the gateway's native Anthropic passthrough (server tools,
# thinking-block signatures, fine-grained streaming); default on. Set to false
# to send Anthropic-backed providers back through the OpenAI-translation path.
@@ -428,7 +430,6 @@ LOG_ONYX_MODEL_INTERACTIONS=False
# NEXT_PUBLIC_DISABLE_LOGOUT=
# NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED=
# NEXT_PUBLIC_THEME=
-# NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=
# NEXT_PUBLIC_CUSTOM_REFRESH_URL=
## Pointer to services
diff --git a/web/Dockerfile b/web/Dockerfile
index f403ec4666..c031d3f504 100644
--- a/web/Dockerfile
+++ b/web/Dockerfile
@@ -51,9 +51,6 @@ ENV NEXT_TELEMETRY_DISABLED=1
ARG NEXT_PUBLIC_THEME
ENV NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME}
-ARG NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED
-ENV NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED}
-
ARG NEXT_PUBLIC_DISABLE_LOGOUT
ENV NEXT_PUBLIC_DISABLE_LOGOUT=${NEXT_PUBLIC_DISABLE_LOGOUT}
@@ -140,9 +137,6 @@ COPY --from=builder --chown=node:node /app/.next/static ./.next/static
ARG NEXT_PUBLIC_THEME
ENV NEXT_PUBLIC_THEME=${NEXT_PUBLIC_THEME}
-ARG NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED
-ENV NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED}
-
ARG NEXT_PUBLIC_DISABLE_LOGOUT
ENV NEXT_PUBLIC_DISABLE_LOGOUT=${NEXT_PUBLIC_DISABLE_LOGOUT}
diff --git a/web/src/app/ee/admin/theme/AppearanceThemeSettings.tsx b/web/src/app/ee/admin/theme/AppearanceThemeSettings.tsx
index e680749a50..42ebd90df6 100644
--- a/web/src/app/ee/admin/theme/AppearanceThemeSettings.tsx
+++ b/web/src/app/ee/admin/theme/AppearanceThemeSettings.tsx
@@ -581,36 +581,6 @@ export const AppearanceThemeSettings = forwardRef<
-