{"record":{"id":"bbf5b884fff55210","repo":"langgenius/dify","slug":"you-don-t-have-the-permission-to-access-the-reques-bbf5b8","errorCode":null,"errorMessage":"You don't have the permission to access the requested resource. It is either read-protected or not readable by the server.","messagePattern":"You don't have the permission to access the requested resource\\. It is either read-protected or not readable by the server\\.","errorType":"exception","errorClass":"Forbidden","httpStatus":403,"severity":"error","filePath":"api/controllers/console/workspace/__init__.py","lineNumber":44,"sourceCode":"            tenant_id = current_tenant_id\n\n            with sessionmaker(db.engine).begin() as session:\n                permission = session.scalar(\n                    select(TenantPluginPermission)\n                    .where(\n                        TenantPluginPermission.tenant_id == tenant_id,\n                    )\n                    .limit(1)\n                )\n\n                if not permission:\n                    # no permission set, allow access for everyone\n                    return view(*args, **kwargs)\n\n                if install_required:\n                    match permission.install_permission:\n                        case TenantPluginInstallPermission.NOBODY:\n                            raise Forbidden()\n                        case TenantPluginInstallPermission.ADMINS:\n                            if not user.is_admin_or_owner:\n                                raise Forbidden()\n                        case TenantPluginInstallPermission.EVERYONE:\n                            pass\n\n                if debug_required:\n                    match permission.debug_permission:\n                        case TenantPluginDebugPermission.NOBODY:\n                            raise Forbidden()\n                        case TenantPluginDebugPermission.ADMINS:\n                            if not user.is_admin_or_owner:\n                                raise Forbidden()\n                        case TenantPluginDebugPermission.EVERYONE:\n                            pass\n\n            return view(*args, **kwargs)\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/workspace/__init__.py#L26-L62","documentation":"werkzeug.exceptions.Forbidden (HTTP 403) with the default message 'You don't have the permission to access the requested resource...'. It is raised by the `plugin_permission_required(install_required=True)` decorator (api/controllers/console/workspace/__init__.py:44) when the tenant's `TenantPluginPermission.install_permission` is `NOBODY`. The decorator only runs when `dify_config.RBAC_ENABLED` is false (RBAC enabled short-circuits at line 22) and a permission row exists for the tenant (no row means open access at line 39). `NOBODY` blocks every account, including the workspace owner, because the matched case raises unconditionally.","triggerScenarios":"Any console endpoint decorated with `@plugin_permission_required(install_required=True)` is hit while the current tenant's `install_permission` is set to `TenantPluginInstallPermission.NOBODY` and RBAC is disabled. The request fails before the view body executes.","commonSituations":"A workspace owner locks down plugin installs to NOBODY in the tenant plugin-permission settings and a user (or the owner themselves) then tries to install/manage a plugin. Permission rows are usually seeded through the plugin-permission admin UI or migrated via DB scripts.","solutions":["Change the tenant's `install_permission` away from NOBODY (to EVERYONE or ADMINS) via the plugin-permission admin setting or by updating the `tenant_plugin_permissions` row.","If install must stay restricted, perform the install as a workspace admin/owner only after switching to ADMINS, since NOBODY cannot be satisfied by any role.","If RBAC is intended to govern access, enable `RBAC_ENABLED` so this decorator is bypassed in favor of `@rbac_permission_required`."],"exampleFix":"// before: install_permission == NOBODY blocks all callers\ncase TenantPluginInstallPermission.NOBODY:\n    raise Forbidden()\n// after: allow admins to install when strict lockdown is not required\ncase TenantPluginInstallPermission.NOBODY:\n    if not user.is_admin_or_owner:\n        raise Forbidden()","handlingStrategy":"validation","validationCode":"# Before calling, check the tenant's plugin install permission\nfrom models.account import TenantPluginInstallPermission\n\nperm = load_tenant_plugin_permission(tenant_id)\nif perm and perm.install_permission == TenantPluginInstallPermission.NOBODY:\n    raise RuntimeError(\"plugin installs are disabled for this workspace (NOBODY)\")","typeGuard":"def install_is_allowed(perm) -> bool:\n    from models.account import TenantPluginInstallPermission\n    return perm is None or perm.install_permission in (\n        TenantPluginInstallPermission.EVERYONE,\n        TenantPluginInstallPermission.ADMINS,\n    )","tryCatchPattern":"from werkzeug.exceptions import Forbidden\ntry:\n    resp = client.post(\"/console/api/workspaces/current/plugin/install\", json=body)\nexcept Forbidden:\n    # install_permission is NOBODY (or ADMINS for non-admins) — surface to user\n    raise PermissionError(\"plugin install is not permitted in this workspace\")","preventionTips":["Document the active TenantPluginPermission setting per workspace so callers know install is locked.","Prefer RBAC over the legacy plugin_permission_required decorator for new endpoints.","When setting install_permission to NOBODY, alert integrations that depend on plugin install."],"tags":["authorization","permissions","plugins","http-403","rbac","werkzeug"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}