feat(rbac): agent RBAC/ACL scenes and resource-locator check bundles (#41768)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Xiyuan Chenandautofix-ci[bot] authored and GitHub committed 2026-09-07 04:39:43 +00:00
1 parent 60e983c493
commit 86134ea99e
152 files changed
+5360 -3405

No files matched your search

@@ -1,7 +1,8 @@
import uuid
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.openapi.auth.composition import account_pipeline, auth_router, external_sso_pipeline
from controllers.openapi.auth.data import RBACRequirement, RequestContext
from controllers.openapi.auth.data import RequestContext
from controllers.openapi.auth.flow import When
from controllers.openapi.auth.pipeline import AuthPipeline, PipelineRoute, PipelineRouter
from controllers.openapi.auth.verify import (
@@ -12,7 +13,7 @@ from controllers.openapi.auth.verify import (
check_workspace_mismatch,
check_workspace_role,
)
from core.rbac import RBACPermission, RBACResourceScope
from core.rbac import RBACPermission
from enums import DeploymentEdition
from libs.oauth_bearer import Scope, TokenType
from models.account import TenantAccountRole
@@ -206,7 +207,7 @@ def _selected_auth_steps_with_rbac(rbac):
def test_account_pipeline_selects_rbac_step_when_required():
rbac = RBACRequirement(resource_type=RBACResourceScope.APP, scene=RBACPermission.APP_VIEW_LAYOUT)
rbac = RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp())
assert check_rbac_permission in _selected_auth_steps_with_rbac(rbac)
@@ -1,5 +1,6 @@
from unittest.mock import patch
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.openapi.auth.conditions import (
EDITION_CLOUD,
EDITION_COMMUNITY,
@@ -18,8 +19,8 @@ from controllers.openapi.auth.conditions import (
data_cond,
request_cond,
)
from controllers.openapi.auth.data import AuthData, RBACRequirement, RequestContext
from core.rbac import RBACPermission, RBACResourceScope
from controllers.openapi.auth.data import AuthData, RequestContext
from core.rbac import RBACPermission
from enums import DeploymentEdition
from libs.oauth_bearer import Scope, TokenType
from models.account import TenantAccountRole
@@ -153,7 +154,7 @@ def test_webapp_run_scoped_false_when_scope_none():
def _rbac_req():
return RBACRequirement(resource_type=RBACResourceScope.APP, scene=RBACPermission.APP_TEST_AND_RUN)
return RBACCheck(RBACPermission.APP_TEST_AND_RUN, PlainApp())
def test_has_rbac_true():
@@ -6,7 +6,8 @@ import pytest
from flask import Flask
from werkzeug.exceptions import Forbidden, NotFound
from controllers.openapi.auth.data import AuthData, RBACRequirement
from controllers.common.rbac import PlainApp, RBACCheck
from controllers.openapi.auth.data import AuthData
from controllers.openapi.auth.verify import (
check_acl,
check_app_access,
@@ -18,7 +19,7 @@ from controllers.openapi.auth.verify import (
check_workspace_mismatch,
check_workspace_role,
)
from core.rbac import RBACPermission, RBACResourceScope
from core.rbac import RBACPermission
from libs.oauth_bearer import Scope, TokenType
from models.account import Tenant, TenantAccountRole
from models.model import App
@@ -85,25 +86,25 @@ def test_check_app_access_raises_when_not_member():
# --- check_rbac_permission ---
_RBAC_REQ = RBACRequirement(resource_type=RBACResourceScope.APP, scene=RBACPermission.APP_VIEW_LAYOUT)
_RBAC_REQ = RBACCheck(RBACPermission.APP_VIEW_LAYOUT, PlainApp())
def test_check_rbac_noop_when_no_requirement():
with patch("controllers.openapi.auth.verify.enforce_rbac_access") as mock_enforce:
with patch("controllers.openapi.auth.verify.enforce_rbac_checks") as mock_enforce:
check_rbac_permission(_data(rbac=None, caller_kind="account"))
mock_enforce.assert_not_called()
def test_check_rbac_noop_when_rbac_disabled(config_overrides: Callable[..., None]):
config_overrides(RBAC_ENABLED=False)
with patch("controllers.openapi.auth.verify.enforce_rbac_access") as mock_enforce:
with patch("controllers.openapi.auth.verify.enforce_rbac_checks") as mock_enforce:
check_rbac_permission(_data(rbac=_RBAC_REQ, caller_kind="account"))
mock_enforce.assert_not_called()
def test_check_rbac_skips_end_user_caller():
with (
patch("controllers.openapi.auth.verify.enforce_rbac_access") as mock_enforce,
patch("controllers.openapi.auth.verify.enforce_rbac_checks") as mock_enforce,
):
check_rbac_permission(_data(rbac=_RBAC_REQ, caller_kind="end_user"))
mock_enforce.assert_not_called()
@@ -126,17 +127,18 @@ def test_check_rbac_enforces_for_account_caller():
path_params={"app_id": "app-1"},
)
with (
patch("controllers.openapi.auth.verify.enforce_rbac_access") as mock_enforce,
patch("controllers.openapi.auth.verify.enforce_rbac_checks") as mock_enforce,
):
check_rbac_permission(data)
mock_enforce.assert_called_once_with(
tenant_id="t1",
account_id=str(account_id),
resource_type=RBACResourceScope.APP,
scene=RBACPermission.APP_VIEW_LAYOUT,
resource_required=True,
path_args={"app_id": "app-1"},
)
mock_enforce.assert_called_once()
call_kwargs = mock_enforce.call_args.kwargs
assert call_kwargs["tenant_id"] == "t1"
assert call_kwargs["account_id"] == str(account_id)
assert call_kwargs["path_args"] == {"app_id": "app-1"}
(check,) = call_kwargs["checks"]
assert isinstance(check, RBACCheck)
assert check.scene is RBACPermission.APP_VIEW_LAYOUT
assert isinstance(check.locator, PlainApp)
def test_check_acl_raises_when_app_or_mode_missing():