Skip to content

Latest commit

 

History

History
110 lines (85 loc) · 4.01 KB

File metadata and controls

110 lines (85 loc) · 4.01 KB

RBAC design

Purpose

Phase 4 adds database-backed role-based access control (RBAC) to AegisAI. It will determine what an authenticated user may do without changing the existing JWT authentication flow.

Authorization model

User ──< user_roles >── Role ──< role_permissions >── Permission
  • A user may have multiple roles.
  • A role may have multiple permissions.
  • Permissions are the smallest unit used to authorize an action.
  • Roles grant permissions; users do not receive direct permission grants in this phase.

The database will be the source of truth. Access tokens identify the user but will not contain roles or permissions. This means role changes and revocations take effect on the next request instead of waiting for an access token to expire.

Permission contract

Permission values use the stable format resource:action. The canonical application values are defined in backend/app/security/permissions.py as PermissionCode.

Permission Intended use
documents:read Read documents and their metadata
documents:write Upload, update, or delete documents
users:read View users for administration
users:manage Activate, deactivate, or otherwise administer users
roles:read View roles and their permissions
roles:manage Create, change, or delete roles and role permissions
roles:assign Assign or remove roles for users

The catalogue is seeded as database records by the Phase 4.3 migration. A new protected capability must add its permission here, seed it through a reviewed migration, and use it in its authorization dependency.

Rules and boundaries

  • Permissions are assigned explicitly to roles; no implicit permission is granted by a role name.

  • New users receive no privileged role automatically.

  • The seeded administrator role receives every canonical permission, but is not assigned automatically. After registering the first operator and applying migrations, run the explicit bootstrap command:

    cd backend
    venv/bin/python -m scripts.bootstrap_administrator admin@example.com
  • Inactive users must not pass permission checks.

  • Role and permission changes are committed transactionally by the service layer, consistent with the authentication implementation.

Not part of Phase 4

The following remain out of scope until later phases:

  • SSO or external identity-provider roles
  • Direct user-to-permission grants or explicit deny rules
  • Role hierarchies and inherited roles
  • Tenant-scoped roles or permissions
  • Audit-log event publishing

Verification

Run the RBAC unit tests from backend/:

venv/bin/python -m unittest discover -s tests -v

They use an isolated in-memory SQLite database to verify the role-to-permission join, assignment and revocation behavior, duplicate-role protection, system-role protection, inactive-user rejection, and 403 permission denial.

Before treating an environment as ready, also verify the real PostgreSQL state inside Compose:

docker compose exec backend alembic upgrade head
docker compose exec backend alembic current
docker compose exec backend python -m scripts.bootstrap_administrator admin@example.com

The final command must target a previously registered operator. Run it a second time to confirm that administrator assignment is idempotent.

Implementation sequence

  1. Define this contract and the permission catalogue (4.1).
  2. Add the RBAC models and schema migration (4.2).
  3. Seed permissions and bootstrap the administrator role (4.3).
  4. Add repositories (4.4) and service operations with transaction boundaries (4.5).
  5. Define typed management APIs (4.6), without registering them until their authorization guard is ready.
  6. Add the require_permission() dependency and register the APIs (4.7). The dependency requires a valid access token, an active user, and the database-backed permission assigned through one of that user's roles.
  7. Verify authorization behavior, bootstrap operations, and migration state (4.8).