diff --git a/.planning/phases/04-rbac/04-CONTEXT.md b/.planning/phases/04-rbac/04-CONTEXT.md new file mode 100644 index 0000000..8821f5c --- /dev/null +++ b/.planning/phases/04-rbac/04-CONTEXT.md @@ -0,0 +1,104 @@ +# Phase 4: RBAC - Context + +**Gathered:** 2026-03-24 +**Status:** Ready for planning + + +## Phase Boundary + +Three-tier role-based access control for the Konstruct portal: platform admin (full SaaS management), customer admin (tenant-scoped full control), and customer operator (read-only + test messages). Includes email invitation flow for tenant user onboarding, role-based portal navigation, API authorization enforcement, and platform admin capabilities (impersonation, global user management). + + + + +## Implementation Decisions + +### Role Definitions & Boundaries +- **Platform admin**: Full access to all tenants, all agents, all users, platform settings. Uses the same portal with elevated access (no separate admin panel). +- **Customer admin**: Full control over their tenant — agents (CRUD), channels, billing (self-service via Stripe), BYO API keys, user management (invite/remove users). Can manage multiple tenants (agency/reseller use case). +- **Customer operator**: View agents, view conversations, view usage dashboards, send test messages to agents. Cannot create/edit/delete agents, no billing access, no API key management, no user management. Fixed role — granular permissions deferred to v2. +- Operators can send test messages to agents — useful for QA without giving edit access. +- Customer admins manage their own billing (subscribe, upgrade, cancel) — self-service, not admin-gated. +- Customer admins manage their own BYO API keys — self-service. + +### Invitation & Onboarding Flow +- Customer admin creates user in portal (name, email, role selection: admin or operator) +- System sends invite email via SMTP direct (no third-party transactional email service) +- Invite link valid for 48 hours — expired links show a clear message +- Customer admin can resend expired invites with a new 48-hour window (resend button on pending invites list) +- All user creation goes through the invite flow — even platform admins must use invites, no direct account creation with temporary passwords. Consistent and auditable. +- Activation page: Claude's discretion (set password only recommended — minimal friction) + +### Portal Experience Per Role +- Role-specific landing pages after login: + - Platform admin → platform overview (all tenants, global stats) + - Customer admin → tenant dashboard (their agents, usage summary) + - Customer operator → agent list (read-only view of their tenant's agents) +- Users with multiple tenants get a tenant switcher dropdown in the sidebar/header — switch without logging out +- Restricted nav items are hidden (not disabled/grayed) — operators don't see Billing, API Keys, User Management in sidebar +- Unauthorized URL access (e.g., operator navigates to /billing) → silent redirect to their home dashboard (no 403 error page) +- API endpoints return 403 Forbidden for unauthorized actions — defense in depth, not just hidden UI + +### Platform Admin Capabilities +- Impersonation: platform admin can "view as" a tenant — all impersonation actions logged in audit trail +- Global user management page: see all users across all tenants, filter by tenant/role, manage invites +- Platform admin sees the same portal as customers but with elevated access and a tenant picker (existing from Phase 1) + +### Claude's Discretion +- Activation page design (set password only vs full profile setup) +- Invite email template content and styling +- SMTP configuration approach (env vars vs portal settings) +- Impersonation UI pattern (banner at top, dropdown, etc.) +- How role is stored in JWT (claim name, encoding) +- Database schema for user-tenant association (join table vs embedded) +- Tenant switcher dropdown visual design + + + + +## Specific Ideas + +- The invite flow should feel professional — "You've been invited to join [Tenant Name] on Konstruct" not generic SaaS boilerplate +- Impersonation should have a clear visual indicator so the admin knows they're viewing as a customer (and can exit easily) +- The tenant switcher should feel instant — no page reload, just context switch +- Operators seeing test message capability makes the role feel useful, not just a "lesser" version of admin + + + + +## Existing Code Insights + +### Reusable Assets +- `packages/shared/shared/models/auth.py:PortalUser` — Existing user model with `is_admin` flag. Needs: `role` enum field, tenant association (many-to-many for multi-tenant support) +- `packages/portal/lib/auth.ts` — Auth.js v5 with JWT callback passing `is_admin`. Needs: pass `role` + `tenant_id` instead, add `tenant_ids` for multi-tenant users +- `packages/shared/shared/api/portal.py` — Auth verify + register endpoints. Needs: role-aware responses, invitation endpoints +- `packages/portal/components/nav.tsx` — Sidebar navigation. Needs: role-based item filtering +- `packages/shared/shared/models/audit.py:AuditEvent` — Immutable audit trail. Reuse for impersonation logging. + +### Established Patterns +- Auth.js v5 JWT strategy — role/tenant info goes in JWT claims, no DB session lookup per request +- FastAPI dependency injection — add role-checking dependencies (`Depends(require_platform_admin)`, `Depends(require_tenant_admin)`) +- PostgreSQL RLS — tenant isolation already enforced at DB level, RBAC is additive authorization on top +- Portal uses TanStack Query — role-filtered API calls will update automatically + +### Integration Points +- Every existing API endpoint needs authorization middleware (currently no auth checks beyond login) +- Portal proxy.ts needs to pass role/tenant from JWT to server components +- Agent Designer, billing, API keys pages need role guards +- New pages needed: user management (per-tenant + global), invite acceptance + + + + +## Deferred Ideas + +- Granular operator permissions (configurable by customer admin) — v2 RBAC enhancement +- SSO/SAML for enterprise tenants — future authentication method +- Activity log visible to customer admins (who did what in their tenant) — separate observability phase + + + +--- + +*Phase: 04-rbac* +*Context gathered: 2026-03-24*