From f1b48a93a925fbbc4da44b8ce936e6ff035fc728 Mon Sep 17 00:00:00 2001 From: Pranav Agarwal Date: Wed, 19 Aug 2026 06:48:15 +0000 Subject: [PATCH] fix(api): enforce edit and RBAC permissions on model provider credential GET endpoints (#40899) (#40900) --- .../console/workspace/model_providers.py | 2 ++ api/controllers/console/workspace/models.py | 2 ++ ...rkspace_credential_mutation_permissions.py | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/api/controllers/console/workspace/model_providers.py b/api/controllers/console/workspace/model_providers.py index 5ff114aa4e0..4e756398c91 100644 --- a/api/controllers/console/workspace/model_providers.py +++ b/api/controllers/console/workspace/model_providers.py @@ -209,6 +209,8 @@ class ModelProviderCredentialApi(Resource): ) @setup_required @login_required + @is_admin_or_owner_required + @rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False) @account_initialization_required @with_current_tenant_id def get(self, tenant_id: str, provider: str): diff --git a/api/controllers/console/workspace/models.py b/api/controllers/console/workspace/models.py index 54d021251fd..02b5a68f9c8 100644 --- a/api/controllers/console/workspace/models.py +++ b/api/controllers/console/workspace/models.py @@ -349,6 +349,8 @@ class ModelProviderModelCredentialApi(Resource): ) @setup_required @login_required + @is_admin_or_owner_required + @rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False) @account_initialization_required @with_current_user @with_current_tenant_id diff --git a/api/tests/unit_tests/controllers/console/test_workspace_credential_mutation_permissions.py b/api/tests/unit_tests/controllers/console/test_workspace_credential_mutation_permissions.py index b7a6212cc75..321c957e79a 100644 --- a/api/tests/unit_tests/controllers/console/test_workspace_credential_mutation_permissions.py +++ b/api/tests/unit_tests/controllers/console/test_workspace_credential_mutation_permissions.py @@ -5,6 +5,8 @@ import pytest from controllers.common.wraps import RBACPermission, RBACResourceScope from controllers.console.datasets.data_source import DataSourceApi +from controllers.console.workspace.model_providers import ModelProviderCredentialApi +from controllers.console.workspace.models import ModelProviderModelCredentialApi from controllers.console.workspace.tool_providers import ToolBuiltinProviderAddApi @@ -26,3 +28,25 @@ def test_workspace_credential_mutations_require_management_permission( assert rbac_config["resource_type"] == RBACResourceScope.WORKSPACE assert rbac_config["scene"] == permission assert rbac_config["resource_required"] is False + + +@pytest.mark.parametrize( + "method", + [ + ModelProviderCredentialApi.get, + ModelProviderModelCredentialApi.get, + ], +) +def test_model_provider_credential_get_requires_admin_and_rbac( + method: FunctionType, +) -> None: + """GET endpoints that return provider credential details must enforce + the same admin + RBAC gates as their sibling POST/PUT/DELETE methods.""" + legacy_wrapper = unwrap(method, stop=lambda wrapper: "is_admin_or_owner_required" in wrapper.__code__.co_qualname) + assert "is_admin_or_owner_required" in legacy_wrapper.__code__.co_qualname + + rbac_wrapper = unwrap(method, stop=lambda wrapper: "rbac_permission_required" in wrapper.__code__.co_qualname) + rbac_config = getclosurevars(rbac_wrapper).nonlocals + assert rbac_config["resource_type"] == RBACResourceScope.WORKSPACE + assert rbac_config["scene"] == RBACPermission.CREDENTIAL_MANAGE + assert rbac_config["resource_required"] is False