wiki/appdoc/doc_security_role_based_access_implementation_plan.md
2025-12-07 13:48:52 +01:00

24 KiB

RBAC Implementation Plan

Overview

This document outlines the implementation plan for migrating from the current User Access Management (UAM) system to the new Role-Based Access Control (RBAC) system as specified in doc_security_role_based_access.md.

Implementation Phases

Phase 1: Database Schema and Data Models

1.1 Create RBAC Data Models

File: gateway/modules/datamodels/datamodelRbac.py

New Models:

  • AccessRuleContext (Enum): DATA, UI, RESOURCE
  • AccessRule (BaseModel): Complete RBAC rule model with context, item, view, read, create, update, delete
  • AccessLevel (Enum): Already exists in datamodelUam.py - verify and ensure consistency

Dependencies:

  • Import from datamodelUam.py: AccessLevel, User
  • Use ModelMixin pattern from existing models
  • Register model labels using registerModelLabels()

Status: AccessLevel already exists in datamodelUam.py Action: Create datamodelRbac.py with AccessRule and AccessRuleContext

1.2 Update User Model

File: gateway/modules/datamodels/datamodelUam.py

Changes:

  • Replace privilege: UserPrivilege with roleLabels: List[str]
  • Update frontend_options to use "user.role" string reference
  • Keep UserPrivilege enum for backward compatibility during migration

Migration Strategy:

  • Add roleLabels field alongside privilege during transition
  • Migration script will populate roleLabels from privilege
  • After migration, privilege can be deprecated

Status: ⚠️ Partial - AccessLevel exists, roleLabels needs to be added

1.3 Database Schema Migration

File: Database migration script (to be created)

Schema Changes:

  1. Create AccessRule table:

    • id (UUID, primary key)
    • roleLabel (string, indexed)
    • context (enum: DATA, UI, RESOURCE, indexed)
    • item (string, nullable, indexed)
    • view (boolean)
    • read (AccessLevel enum, nullable)
    • create (AccessLevel enum, nullable)
    • update (AccessLevel enum, nullable)
    • delete (AccessLevel enum, nullable)
    • Standard fields: _createdAt, _createdBy, _updatedAt, _updatedBy
  2. Update User table:

    • Add roleLabels column (array of strings)
    • Keep privilege column for backward compatibility
  3. Create indexes:

    • AccessRule(roleLabel, context, item) - composite index for rule lookups
    • AccessRule(context, item) - for context/item queries

Status: 📝 To be implemented


Phase 2: RBAC Interface and Core Logic

2.1 Create RBAC Interface

File: gateway/modules/interfaces/interfaceRbac.py

Purpose: Centralized RBAC logic and permission resolution

Key Functions:

  • getUserPermissions(user: User, context: AccessRuleContext, item: str) -> UserPermissions
  • findMostSpecificRule(rules: List[AccessRule], item: str) -> Optional[AccessRule]
  • validateAccessRule(rule: AccessRule) -> bool
  • _isMorePermissive(level1: AccessLevel, level2: AccessLevel) -> bool

Dependencies:

  • datamodelRbac.py: AccessRule, AccessRuleContext
  • datamodelUam.py: User, UserPermissions, AccessLevel
  • connectorDbPostgre.py: Database connector for rule queries

References Check:

  • Can import from datamodelUam.py and datamodelRbac.py
  • Can use database connector from interfaceDbAppObjects.py pattern
  • Follows same pattern as interfaceDbAppAccess.py

Status: 📝 To be implemented

2.2 Integrate RBAC CRUD into AppObjects Interface

File: gateway/modules/interfaces/interfaceDbAppObjects.py

New Methods (camelCase):

  • createAccessRule(accessRule: AccessRule) -> AccessRule
  • getAccessRule(ruleId: str) -> Optional[AccessRule]
  • updateAccessRule(ruleId: str, accessRule: AccessRule) -> AccessRule
  • deleteAccessRule(ruleId: str) -> bool
  • getAccessRules(roleLabel: Optional[str] = None, context: Optional[AccessRuleContext] = None, item: Optional[str] = None) -> List[AccessRule]
  • getAccessRulesForRoles(roleLabels: List[str], context: AccessRuleContext, item: str) -> List[AccessRule]

Integration Points:

  • Use existing self.db.recordCreate(), self.db.recordUpdate(), self.db.recordDelete(), self.db.getRecordset() methods
  • Follow same pattern as existing CRUD methods (e.g., createUser(), updateUser())
  • Add RBAC permission checks using interfaceRbac.getUserPermissions()

References Check:

  • Can use self.db database connector (already initialized)
  • Can import AccessRule from datamodelRbac.py
  • Follows existing interface pattern

Status: 📝 To be implemented


Phase 3: Database Bootstrap and Initialization

3.1 Create Centralized Bootstrap Interface

File: gateway/modules/interfaces/interfaceBootstrap.py

Purpose: Centralized bootstrap module containing all initialization logic, specific data (roles, user names, mandate profiles), and RBAC rules converted from existing UAM logic.

Key Functions:

  • initBootstrap(db: DatabaseConnector) -> None - Main bootstrap entry point
  • initRootMandate(db: DatabaseConnector) -> str - Creates root mandate, returns mandateId
  • initAdminUser(db: DatabaseConnector, mandateId: str) -> str - Creates admin user, returns userId
  • initEventUser(db: DatabaseConnector, mandateId: str) -> str - Creates event user, returns userId
  • initRbacRules(db: DatabaseConnector) -> None - Creates all RBAC rules from UAM logic
  • createDefaultRoleRules(db: DatabaseConnector) -> None - Creates default role rules
  • createTableSpecificRules(db: DatabaseConnector) -> None - Creates table-specific rules from UAM logic
  • assignInitialUserRoles(db: DatabaseConnector, adminUserId: str, eventUserId: str) -> None - Assigns roles to initial users

Bootstrap Data Configuration:

  • Root Mandate: name="Root", language="en", enabled=True
  • Admin User: username="admin", email="admin@example.com", fullName="Administrator", roleLabels=["sysadmin"]
  • Event User: username="event", email="event@example.com", fullName="Event", roleLabels=["sysadmin"]
  • Roles: sysadmin, admin, user, viewer

RBAC Rules to Create (converted from interfaceDbAppAccess.py logic):

  1. Generic Role Rules (context: DATA, item: null):

    • sysadmin: view=true, read="a", create="a", update="a", delete="a"
    • admin: view=true, read="g", create="g", update="g", delete="n"
    • user: view=true, read="m", create="m", update="m", delete="m"
    • viewer: view=true, read="g", create="n", update="n", delete="n"
  2. Table-Specific Rules (context: DATA, item: <table>):

    • Mandate:

      • sysadmin: view=true, read="a", create="a", update="a", delete="a"
      • admin/user/viewer: view=false (no access)
    • UserInDB:

      • sysadmin: view=true, read="a", create="a", update="a", delete="a"
      • admin: view=true, read="g", create="g", update="g", delete="g" (mandate scope)
      • user/viewer: view=true, read="m", create="n", update="m", delete="n" (own records only)
    • UserConnection:

      • sysadmin: view=true, read="a", create="a", update="a", delete="a"
      • admin: view=true, read="g", create="g", update="g", delete="g" (users in mandate)
      • user/viewer: view=true, read="m", create="m", update="m", delete="m" (own connections)
    • DataNeutraliserConfig:

      • sysadmin: view=true, read="a", create="a", update="a", delete="a"
      • admin: view=true, read="g", create="g", update="g", delete="g" (mandate scope)
      • user/viewer: view=true, read="m", create="m", update="m", delete="m" (own configs)
    • DataNeutralizerAttributes:

      • sysadmin: view=true, read="a", create="a", update="a", delete="a"
      • admin: view=true, read="g", create="g", update="g", delete="g" (mandate scope)
      • user/viewer: view=true, read="m", create="m", update="m", delete="m" (own attributes)
    • AuthEvent:

      • sysadmin/admin: view=true, read="a", create="n", update="n", delete="a"
      • user/viewer: view=true, read="m", create="n", update="n", delete="n" (own events only)
    • Default Tables (all other tables):

      • sysadmin: view=true, read="a", create="a", update="a", delete="a"
      • admin: view=true, read="g", create="g", update="g", delete="g" (mandate scope)
      • user/viewer: view=true, read="m", create="m", update="m", delete="m" (own records)
  3. UI Context Rules (context: UI):

    • Generic UI access for all roles (to be defined based on requirements)
    • Component-specific rules as needed
  4. RESOURCE Context Rules (context: RESOURCE):

    • AI model access rules (to be defined based on requirements)
    • Action access rules (to be defined based on requirements)

Integration with AppObjects Interface: File: gateway/modules/interfaces/interfaceDbAppObjects.py

Replace _initRecords() method:

def _initRecords(self):
    """Initialize standard records if they don't exist."""
    from modules.interfaces.interfaceBootstrap import initBootstrap
    initBootstrap(self.db)

Remove Methods (moved to interfaceBootstrap.py):

  • _initRootMandate()interfaceBootstrap.initRootMandate()
  • _initAdminUser()interfaceBootstrap.initAdminUser()
  • _initEventUser()interfaceBootstrap.initEventUser()

Status: 📝 To be implemented

3.2 UAM Logic to RBAC Rules Conversion

Source Files to Analyze:

  • gateway/modules/interfaces/interfaceDbAppAccess.py
  • gateway/modules/interfaces/interfaceDbChatAccess.py
  • gateway/modules/interfaces/interfaceDbComponentAccess.py

Conversion Mapping:

UAM Logic (interfaceDbAppAccess.py) RBAC Rule (context: DATA)
table_name == "Mandate" + privilege == SYSADMIN roleLabel="sysadmin", item="Mandate", view=true, read="a", create="a", update="a", delete="a"
table_name == "UserInDB" + privilege == SYSADMIN roleLabel="sysadmin", item="UserInDB", view=true, read="a", create="a", update="a", delete="a"
table_name == "UserInDB" + privilege == ADMIN roleLabel="admin", item="UserInDB", view=true, read="g", create="g", update="g", delete="g"
table_name == "UserInDB" + privilege == USER roleLabel="user", item="UserInDB", view=true, read="m", create="n", update="m", delete="n"
table_name == "UserConnection" + privilege == SYSADMIN roleLabel="sysadmin", item="UserConnection", view=true, read="a", create="a", update="a", delete="a"
table_name == "UserConnection" + privilege == ADMIN roleLabel="admin", item="UserConnection", view=true, read="g", create="g", update="g", delete="g"
table_name == "UserConnection" + privilege == USER roleLabel="user", item="UserConnection", view=true, read="m", create="m", update="m", delete="m"
table_name == "DataNeutraliserConfig" + privilege == SYSADMIN roleLabel="sysadmin", item="DataNeutraliserConfig", view=true, read="a", create="a", update="a", delete="a"
table_name == "DataNeutraliserConfig" + privilege == ADMIN roleLabel="admin", item="DataNeutraliserConfig", view=true, read="g", create="g", update="g", delete="g"
table_name == "DataNeutraliserConfig" + privilege == USER roleLabel="user", item="DataNeutraliserConfig", view=true, read="m", create="m", update="m", delete="m"
table_name == "DataNeutralizerAttributes" + privilege == SYSADMIN roleLabel="sysadmin", item="DataNeutralizerAttributes", view=true, read="a", create="a", update="a", delete="a"
table_name == "DataNeutralizerAttributes" + privilege == ADMIN roleLabel="admin", item="DataNeutralizerAttributes", view=true, read="g", create="g", update="g", delete="g"
table_name == "DataNeutralizerAttributes" + privilege == USER roleLabel="user", item="DataNeutralizerAttributes", view=true, read="m", create="m", update="m", delete="m"
table_name == "AuthEvent" + privilege in [SYSADMIN, ADMIN] roleLabel="sysadmin"/"admin", item="AuthEvent", view=true, read="a", create="n", update="n", delete="a"
table_name == "AuthEvent" + privilege == USER roleLabel="user", item="AuthEvent", view=true, read="m", create="n", update="n", delete="n"
Default tables + privilege == SYSADMIN roleLabel="sysadmin", item=null, view=true, read="a", create="a", update="a", delete="a"
Default tables + privilege == ADMIN roleLabel="admin", item=null, view=true, read="g", create="g", update="g", delete="g"
Default tables + privilege == USER roleLabel="user", item=null, view=true, read="m", create="m", update="m", delete="m"

Implementation Steps:

  1. Read interfaceDbAppAccess.py and extract all uam() logic
  2. Read interfaceDbChatAccess.py and extract all uam() logic
  3. Read interfaceDbComponentAccess.py and extract all uam() logic
  4. Map each permission check to RBAC rule format
  5. Create AccessRule entries in interfaceBootstrap.createTableSpecificRules()
  6. Test that RBAC rules produce same results as UAM logic

Status: 📝 To be implemented


Phase 4: Database Connector RBAC Support

4.1 Extend Database Connector

File: gateway/modules/connectors/connectorDbPostgre.py

New Methods:

  • getRecordsetWithRBAC(modelClass: Type[BaseModel], currentUser: User, recordFilter: Dict = None, orderBy: str = None, limit: int = None) -> List[Dict]
  • buildRbacWhereClause(accessRules: List[AccessRule], currentUser: User) -> str
  • executeQueryWithRbac(...) -> List[Dict]

SQL Query Enhancement:

  • Modify SQL generation to include RBAC WHERE clauses
  • Support multiple roles with UNION logic
  • Optimize queries with proper indexes

Status: 📝 To be implemented


Phase 5: Migration from UAM to RBAC

5.1 Create Migration Script

File: gateway/modules/migration/migrateUamToRbac.py

Migration Steps:

  1. Schema Migration:

    • Create AccessRule table
    • Add roleLabels column to User table
    • Create indexes
  2. Data Migration:

    • Convert User.privilegeUser.roleLabels:
      • UserPrivilege.SYSADMIN["sysadmin"]
      • UserPrivilege.ADMIN["admin"]
      • UserPrivilege.USER["user"]
    • Create default access rules based on current UAM logic
    • Map existing table-specific permissions to RBAC rules
  3. Validation:

    • Verify all users have roleLabels assigned
    • Verify access rules match current UAM behavior
    • Test permission resolution

Status: 📝 To be implemented

5.2 Update Interface Methods

Files to Update:

  • gateway/modules/interfaces/interfaceDbAppObjects.py
  • gateway/modules/interfaces/interfaceDbChatObjects.py
  • gateway/modules/interfaces/interfaceDbComponentObjects.py

Changes:

  • Replace _uam() calls with getRecordsetWithRBAC()
  • Replace _canModify() checks with RBAC permission checks
  • Update all getRecordset() calls to use RBAC filtering

Status: 📝 To be implemented


Phase 6: UI and Resource Access Control

6.1 UI Access Control Integration

Files: Frontend integration (out of scope for backend)

Backend Support:

  • Ensure getUserPermissions() works for UI context
  • Create API endpoint: GET /api/rbac/permissions?context=UI&item=playground.voice.settings
  • Return UserPermissions model with view attribute

Status: 📝 To be implemented

6.2 Resource Access Control Integration

Files: Feature modules that use resources

Integration Points:

  • AI model selection: Check getUserPermissions(context=RESOURCE, item="ai.model.anthropic")
  • Action execution: Check permissions before allowing action execution
  • Create helper functions in feature modules

Status: 📝 To be implemented


Phase 7: Testing and Validation

7.1 Unit Tests

Files: gateway/tests/unit/rbac/

Test Cases:

  • Permission resolution (single role, multiple roles)
  • Rule specificity (generic vs specific)
  • Opening rights principle
  • System field protection
  • Bootstrap initialization

Status: 📝 To be implemented

7.2 Integration Tests

Files: gateway/tests/integration/rbac/

Test Cases:

  • Database queries with RBAC filtering
  • User CRUD operations with RBAC
  • Multi-role permission combination
  • Migration from UAM to RBAC

Status: 📝 To be implemented

7.3 Performance Tests

Test Cases:

  • Query performance with RBAC (compare to current UAM)
  • Memory usage reduction
  • Database load reduction

Status: 📝 To be implemented


Module Adaptation Summary

Modules to Create

  1. gateway/modules/datamodels/datamodelRbac.py

    • AccessRule model
    • AccessRuleContext enum
    • Model label registration
  2. gateway/modules/interfaces/interfaceRbac.py

    • RBAC core logic
    • Permission resolution functions
    • Rule validation functions
  3. gateway/modules/interfaces/interfaceBootstrap.py NEW

    • Centralized bootstrap interface
    • All initialization logic (mandate, users, RBAC rules)
    • Bootstrap data configuration (roles, user names, mandate profiles)
    • RBAC rules converted from UAM logic (interfaceDbAppAccess.py, interfaceDbChatAccess.py, interfaceDbComponentAccess.py)
  4. gateway/modules/migration/migrateUamToRbac.py

    • Migration script
    • Data transformation logic
    • Validation functions

Modules to Adapt

  1. gateway/modules/datamodels/datamodelUam.py ⚠️ KEEP - Still Needed

    • Add AccessLevel enum (already done)
    • Add UserPermissions model (already done)
    • 📝 Add roleLabels: List[str] to User model
    • 📝 Update frontend_options to use string references
    • ⚠️ Keep: User, Mandate, UserConnection models (core data structures)
    • ⚠️ Deprecate: UserPrivilege enum (replaced by roleLabels with RBAC)
  2. gateway/modules/interfaces/interfaceDbAppObjects.py

    • 📝 Add RBAC CRUD methods
    • 📝 Replace _initRecords() to call interfaceBootstrap.initBootstrap()
    • 📝 Remove _initRootMandate(), _initAdminUser(), _initEventUser() (moved to interfaceBootstrap.py)
    • 📝 Replace _uam() with RBAC-based filtering (Phase 5)
    • 📝 Remove self.access initialization (no longer needed after RBAC migration)
  3. gateway/modules/connectors/connectorDbPostgre.py

    • 📝 Add getRecordsetWithRBAC() method
    • 📝 Add buildRbacWhereClause() method
    • 📝 Add executeQueryWithRbac() method
    • 📝 Enhance SQL generation for RBAC
  4. gateway/modules/interfaces/interfaceDbChatObjects.py

    • 📝 Replace _uam() calls with RBAC filtering
    • 📝 Update permission checks to use RBAC
  5. gateway/modules/interfaces/interfaceDbComponentObjects.py

    • 📝 Replace _uam() calls with RBAC filtering
    • 📝 Update permission checks to use RBAC
  6. gateway/modules/features/options/mainOptions.py (if created)

    • 📝 Ensure getOptions() function exists for dynamic options

Modules to Remove (After Refactoring)

  1. gateway/modules/interfaces/interfaceDbAppAccess.py REMOVE after Phase 5

    • ⚠️ Convert all UAM logic to RBAC rules in interfaceBootstrap.py
    • Current UAM logic (uam(), canModify()) converted to AccessRule entries
    • Action: Extract all permission logic from uam() and canModify() methods
    • Action: Convert to RBAC rules in interfaceBootstrap.createTableSpecificRules()
    • Remove after all interfaces migrated to RBAC and rules validated
  2. gateway/modules/interfaces/interfaceDbChatAccess.py REMOVE after Phase 5

    • ⚠️ Convert all UAM logic to RBAC rules in interfaceBootstrap.py
    • Similar to interfaceDbAppAccess.py
    • Extract permission logic and convert to RBAC rules
    • Remove after migration complete
  3. gateway/modules/interfaces/interfaceDbComponentAccess.py REMOVE after Phase 5

    • ⚠️ Convert all UAM logic to RBAC rules in interfaceBootstrap.py
    • Similar to interfaceDbAppAccess.py
    • Extract permission logic and convert to RBAC rules
    • Remove after migration complete

Migration Strategy for Access Modules:

  1. Phase 3: Analyze all interface*Access.py modules
  2. Phase 3: Extract permission logic from uam() and canModify() methods
  3. Phase 3: Convert to RBAC rules in interfaceBootstrap.createTableSpecificRules()
  4. Phase 5: Replace all _uam() calls with RBAC filtering
  5. Phase 5: Remove self.access initialization from interfaces
  6. Phase 9-10: Delete interface*Access.py modules after validation

Note: Keep these modules during migration for backward compatibility. Remove only after:

  • All UAM logic converted to RBAC rules in bootstrap
  • All interfaces use RBAC
  • All tests pass
  • Migration validation complete
  • No references to old UAM methods remain

Database Schema Changes

  1. New Table: AccessRule
  2. Modified Table: User (add roleLabels column)
  3. New Indexes: Performance optimization for RBAC queries

Implementation Timeline

Week 1-2: Foundation

  • Create datamodelRbac.py with AccessRule model
  • Create interfaceRbac.py with core RBAC logic
  • Create interfaceBootstrap.py with centralized bootstrap logic
  • Extract bootstrap logic from interfaceDbAppObjects.py to interfaceBootstrap.py
  • Analyze interface*Access.py modules and extract UAM logic
  • Convert UAM logic to RBAC rules in interfaceBootstrap.py
  • Update datamodelUam.py with roleLabels field
  • Integrate interfaceBootstrap.initBootstrap() into interfaceDbAppObjects.py

Week 3-4: Database Integration

  • 📝 Extend database connector with RBAC support
  • 📝 Create migration script
  • 📝 Test database schema changes
  • 📝 Validate bootstrap initialization

Week 5-6: Interface Migration

  • 📝 Add RBAC CRUD methods to interfaceDbAppObjects.py
  • 📝 Update interfaceDbChatObjects.py to use RBAC
  • 📝 Update interfaceDbComponentObjects.py to use RBAC
  • 📝 Replace _uam() calls with RBAC filtering

Week 7-8: Testing & Optimization

  • 📝 Write unit tests
  • 📝 Write integration tests
  • 📝 Performance testing
  • 📝 Query optimization
  • 📝 Documentation updates

Week 9-10: Cleanup & Deprecation

  • 📝 Remove interfaceDbAppAccess.py (UAM logic converted to RBAC rules)
  • 📝 Remove interfaceDbChatAccess.py (UAM logic converted to RBAC rules)
  • 📝 Remove interfaceDbComponentAccess.py (UAM logic converted to RBAC rules)
  • 📝 Deprecate UserPrivilege enum in datamodelUam.py (keep for backward compatibility, mark as deprecated)
  • 📝 Final validation
  • 📝 Production deployment

Risk Mitigation

Backward Compatibility

  • Keep UserPrivilege enum during migration
  • Maintain _uam() method alongside RBAC during transition
  • Gradual migration allows rollback if needed

Data Integrity

  • Migration script with validation
  • Backup before migration
  • Test migration on staging environment first

Performance

  • Index optimization for RBAC queries
  • Query performance testing before production
  • Monitor database load after deployment

Success Criteria

  1. All users have roleLabels assigned
  2. All access rules created and validated
  3. RBAC filtering works for all data operations
  4. Performance meets or exceeds current UAM system
  5. All tests pass
  6. No deprecated UAM code remains
  7. Documentation updated

Notes

  • Follow camelCase naming convention for all functions and variables
  • Internal functions use _ prefix
  • Use Pydantic models for type safety
  • Maintain existing error handling patterns
  • Follow existing logging patterns

Important Clarifications

datamodelUam.py Status

  • KEEP: Core data models (User, Mandate, UserConnection) are still needed
  • KEEP: AccessLevel enum (used by RBAC)
  • KEEP: UserPermissions model (used by RBAC)
  • ⚠️ DEPRECATE: UserPrivilege enum (replaced by roleLabels with RBAC rules)
  • 📝 ADD: roleLabels: List[str] field to User model

interface*Access.py Modules Status

  • REMOVE: All interface*Access.py modules after migration
  • ⚠️ CONVERT: All UAM logic from these modules to RBAC rules in interfaceBootstrap.py
  • 📝 ACTION: Extract permission logic from uam() and canModify() methods
  • 📝 ACTION: Create corresponding AccessRule entries in bootstrap

Bootstrap Strategy

  • CENTRALIZE: All bootstrap logic in interfaceBootstrap.py
  • 📝 INCLUDE: Mandate creation, user creation, RBAC rule initialization
  • 📝 INCLUDE: All bootstrap data (roles, user names, mandate profiles)
  • 📝 INCLUDE: RBAC rules converted from UAM logic