Files
dss/.knowledge/adrs/006-rbac-admin-principles.md
Digital Production Factory 276ed71f31 Initial commit: Clean DSS implementation
Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm

Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)

Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability

Migration completed: $(date)
🤖 Clean migration with full functionality preserved
2025-12-09 18:45:48 -03:00

6.0 KiB

ADR-006: Role-Based Access Control for Admin Principles

Status: Accepted Date: 2025-12-08 Deciders: DSS Architecture Team (via Zen Swarm 3-Cycle Analysis) Related: ADMIN_PRINCIPLES.md v2.0.0, PRINCIPLES.md v2.2.0

Context

The DSS Admin layer requires team-specific access control to enable role-based dashboards and one-click operations. Four distinct teams need different capabilities:

  • Admin Team: System configuration, project creation, user/role management
  • UI Team: Figma sync, QuickWins analysis, regression tools
  • UX Team: Component/token/icon management, Figma plugin customization
  • QA Team: Component testing, ESRE, issue creation

The existing role system (admin, designer, developer, viewer) was generic and didn't align with team-specific workflows described in Admin Principle #6 (Role-Based Configuration & Visibility).

Decision

We implemented a comprehensive RBAC layer with:

1. Team-Aligned Role System

  • Replaced generic roles with team-specific roles: admin, ui_team, ux_team, qa_team
  • Added team_id field to User model for multi-team organization support
  • Default role: ui_team (safest non-admin default)

2. Granular Permission Model

Created TeamPermissions table with:

  • Triple: (role, resource, action) with unique constraint
  • Actions: CRUD (create, read, update, delete)
  • Resources: figma, components, tokens, icons, analysis, metrics, issues, testing
  • Admin Bypass: Admins have implicit all-permissions without database checks

3. Middleware Architecture

  • authenticateToken: JWT validation (existing)
  • authorizeRole(allowedRoles): Simple role checking (existing, updated)
  • requirePermission(resource, action): Granular permission checking (new)

4. Admin API Endpoints

Four new endpoints in /api/admin/roles/:

  • POST /assign: Assign role to user (admin-only)
  • GET /permissions/:role: View role permissions (self or admin)
  • PUT /permissions/:role: Enable/disable permissions (admin-only)
  • GET /users/:user_id/permissions: View effective user permissions (self or admin)

5. Database Migration Strategy

Used temporary column pattern to safely migrate PostgreSQL ENUMs:

Users.role (old enum) → Users.role_new (new enum) → drop old → rename new → set constraints

This avoids casting errors and allows atomic rollback.

Alternatives Considered

Alternative 1: Attribute-Based Access Control (ABAC)

Rejected: Too complex for current needs. RBAC with granular permissions provides sufficient flexibility.

Alternative 2: Single Admin Role with Feature Flags

Rejected: Doesn't support team-specific audit trails or permission boundaries required by Admin Principle #3 (Accountability).

Alternative 3: External Authorization Service (e.g., Ory Keto, Casbin)

Rejected: Adds operational complexity and external dependency. In-database RBAC is sufficient for DSS scale.

Consequences

Positive

  • Team Alignment: Roles now match organizational structure
  • Granular Control: Permissions can be toggled per team without code changes
  • Audit Trail: TeamPermissions changes logged in database
  • Migration Safety: Temporary column pattern allows zero-downtime deployment
  • Admin Lockout Prevention: Admin bypass ensures system recoverability

Negative

  • Performance: N+1 query on every requirePermission check (see Mitigation)
  • Complexity: Additional table and migration logic
  • Language Mismatch: Implemented in JavaScript instead of TypeScript (technical debt)

Neutral

  • Breaking Change: Old roles mapped to new roles during migration (graceful upgrade path)

Mitigation Strategies

Critical: Redis Caching (Next Step)

To address the N+1 performance issue, Track 1.5 will implement:

  • Redis cache for permissions: rbac:permissions:{role} (TTL: 1 hour)
  • Cache invalidation on permission updates
  • Fallback to database on cache miss

Security Hardening

  • Remove hardcoded JWT secret fallback (process.env.JWT_SECRET || 'your-secret-key')
  • Throw error on app startup if JWT_SECRET undefined

TypeScript Migration (Future)

  • Convert models and middleware to TypeScript for type safety
  • Add .d.ts definitions for Sequelize models

Implementation Details

Files Modified:

  • server/src/models/User.js: Added role enum and team_id field
  • server/src/middleware/auth.js: Added requirePermission middleware

Files Created:

  • server/src/models/TeamPermissions.js: Permission model
  • server/src/routes/admin/roles.js: Role management API
  • server/migrations/20251208000000-add-rbac.js: Database migration

Default Permissions Seeded:

  • ui_team: sync_figma, view_figma, quickwins, regression, view_metrics
  • ux_team: view/update components/tokens/icons, customize_figma_plugin, view_metrics
  • qa_team: test_components, create_issue, view_metrics, run_esre

Validation

Cycle 1 (ThinkDeep): Architecture validated with "almost_certain" confidence Cycle 2 (Gemini 3 Pro): Code generation completed Cycle 3 (Gemini 3 Pro Review): Security, architecture, performance, code quality validated

Review Findings:

  • Migration strategy: Excellent
  • Database design: Solid (unique constraints, transactions)
  • API design: RESTful, consistent response format
  • ⚠️ Performance: Redis caching required
  • ⚠️ Security: Remove hardcoded secret fallback
  • ⚠️ Architecture: TypeScript conversion recommended

Next Steps

  1. Track 1.5: Implement Redis caching for permissions (immediate)
  2. Track 2: Configuration Schema (system/project/user tiers)
  3. Track 3: Component Registry (automatic discovery)
  4. Track 4: OAuth Integration (Figma/Atlassian)

References