-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Priority: P0 (Critical)
Phase: 1 - E-Commerce Core
Estimate: 3 days
Type: Story
Context
Introduce Role-Based Access Control with per-organization scoping and scoped API tokens to prevent privilege escalation and cross-tenant data exposure.
Scope
- Roles: OWNER, ADMIN, MANAGER, STAFF, VIEWER (enum)
- Membership: extend existing Membership model (ensure unique (userId, organizationId))
- Permission Matrix (draft):
- OWNER: all + billing + destructive
- ADMIN: all minus billing destructive
- MANAGER: products, inventory, orders, limited staff management
- STAFF: orders fulfillment + inventory adjust
- VIEWER: read-only
- API Tokens:
ApiTokenmodel (tokenHash, organizationId, scopes[], lastUsedAt, expiresAt, createdByUserId) - Scopes (initial): products:rw, inventory:rw, orders:rw, payments:rw, webhooks:rw, billing:r, analytics:r
- Middleware: server-side guard builder
requireScope(scopes: string[])&requireRole(minRole)utilities - Prisma query pattern enforcement: ALWAYS filter by organization and authorized scope
Acceptance Criteria
- Server actions reject access without required role/scope
- API Token can be created by OWNER/ADMIN only
- Token hashed (SHA-256) stored, raw shown once
- Invalid/expired token returns 401 (never ambiguous 404 for auth boundaries)
- Attempts logged with structured context (orgId, userId/tokenId, route, scopes)
- Scopes enforced on at least 3 critical endpoints (product create, inventory adjustment, order read)
- Role downgrade prevents previous elevated actions immediately
Data Model (Draft)
model ApiToken {
id String @id @default(cuid())
organizationId String
tokenHash String @unique
name String
scopes String[] // store as text[] in Postgres
expiresAt DateTime?
lastUsedAt DateTime?
createdByUserId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId])
}Dependencies
- Builds on: existing Membership & Organization models
- Enables: future audit trail (#TBD Observability) & external integrations security
Metrics
- Unauthorized access attempts captured 100%
- Token scope mismatch error rate baseline recorded
- Mean authorization check overhead < 2ms
Testing Checklist
- Token with missing scope denied
- Role downgrade reflects immediately (simulate OWNER→STAFF)
- Expired token fails
- Organization isolation enforced (attempt cross-org access fails)
Risk
High integrity & security impact (score: 18). Prevents cross-tenant leakage & abuse.
References
- docs/GITHUB_ISSUES_COMPARISON_ANALYSIS.md (RBAC gap section)
Copilot