Skip to content

feat: per-user module permissions (RBAC) with admin bypass - #276

Merged
jubaoliang merged 2 commits into
developfrom
feature/user-module-permissions
Aug 14, 2026
Merged

jubaoliang merged 2 commits into
developfrom
feature/user-module-permissions

Conversation

@jubaoliang

Copy link
Copy Markdown
Collaborator

Summary

Adds a module-level permission system so non-admin users can be scoped to a subset of dashboard modules. This is the backend + dashboard RBAC groundwork; admin always bypasses every gate.

  • New permissions TEXT column on the users table (migration 006, both SQLite and PostgreSQL).
  • Central permission catalog in src/octop/infra/users/permissions.py (keyed by nav module: settings / control / admin), with user_has_permission, validate_permission_keys, and effective_permissions.
  • Backend ACL enforcement across routers via a require_permission(...) dependency and direct user_has_permission checks (terminal WS, knowledge, etc.).
  • Dashboard gating by nav module using new RequirePermission + ForbiddenPage components, replacing the old RequireAdmin guard.
  • admin bypasses all gates; read access and chat/agent use are never gated.
  • Permission catalog exposed on /auth/me and a permission picker in the user admin panel.

Test plan

  • make all is green (format + lint + typecheck + backend tests + dashboard tsc build).
  • Added unit/integration coverage: test_permissions.py, test_permissions_api.py, test_acl_gate_coverage.py, test_user_permissions_column.py, test_knowledge_hint.py, etc.
  • Fixed terminal WS test fixtures to carry permissions=["terminal"].

Notes

  • uv.lock was intentionally excluded from this PR: the only diff there is upload-time metadata added by a newer uv re-lock, with no real dependency change.

jubaoliang-tencent and others added 2 commits August 14, 2026 04:10
Introduce a module-level permission system so non-admin users can be
scoped to a subset of dashboard modules. Adds a `permissions` TEXT column
on the `users` table (migration 006, SQLite + PostgreSQL), a central
permission catalog in `infra/users/permissions.py`, backend ACL checks
across routers, and dashboard gating via `RequirePermission` /
`ForbiddenPage` keyed by nav module. `admin` always bypasses every gate;
read access and chat/agent use are never gated.

Co-Authored-By: CodeBuddy <codebuddy@tencent.com>
…nly)

The host CLI installer is a connectors-module operation and should be
gated by the `connectors` module permission, consistent with the rest of
the connector routes, instead of being admin-only.

The earlier RBAC change demoted this route from `current_admin` but the
test `test_install_cli_forbidden_for_non_admin` still failed because the
`create_user` test helper grants `BASELINE_PERMISSIONS` (which includes
`connectors`) by default, so the "non-admin" user actually held the
permission. Gate the route with `require_permission("connectors")` and
create the test user with `permissions=[]` so it genuinely lacks the
key and is rejected with 403.

Co-Authored-By: CodeBuddy <codebuddy@tencent.com>
@jubaoliang
jubaoliang force-pushed the feature/user-module-permissions branch from 50ae9df to 0e6038d Compare August 14, 2026 05:03
@jubaoliang
jubaoliang merged commit 041628c into develop Aug 14, 2026
3 checks passed
@jubaoliang
jubaoliang deleted the feature/user-module-permissions branch September 17, 2026 07:24
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.

2 participants