# ColaFlow M1.2 Feature List - Enterprise Multi-Tenant Architecture **Document Type:** Feature Requirements & Acceptance Criteria **Milestone:** M1.2 (Enterprise Multi-Tenant Architecture) **Version:** 1.0 **Date:** 2025-11-03 **Owner:** Product Manager **Status:** Approved for Development --- ## Document Overview This document defines the complete feature set for ColaFlow M1.2, the Enterprise Multi-Tenant Architecture milestone. It includes functional requirements, non-functional requirements, acceptance criteria, technical requirements, and security requirements for all features. **M1.2 Scope:** Transform ColaFlow from single-tenant to enterprise-ready multi-tenant SaaS platform with SSO and AI agent authentication. --- ## Table of Contents 1. [Feature Overview](#feature-overview) 2. [Feature Categories](#feature-categories) 3. [Detailed Feature Specifications](#detailed-feature-specifications) 4. [Non-Functional Requirements](#non-functional-requirements) 5. [Technical Requirements](#technical-requirements) 6. [Security Requirements](#security-requirements) 7. [Acceptance Criteria Matrix](#acceptance-criteria-matrix) --- ## Feature Overview ### M1.2 Goals 1. **Multi-Tenancy:** Support multiple companies (tenants) on shared infrastructure 2. **SSO Integration:** Enable enterprise SSO (Azure AD, Google, Okta, SAML 2.0) 3. **MCP Authentication:** Secure AI agent access via MCP tokens 4. **Tenant Management:** Self-service tenant registration and administration 5. **Data Isolation:** Ensure complete data separation between tenants ### Feature Summary | Feature Category | Features Count | Priority | Status | |------------------|----------------|----------|--------| | **Multi-Tenancy** | 6 | P0 (Must Have) | In Development | | **Authentication** | 4 | P0 (Must Have) | Planned | | **SSO Integration** | 5 | P1 (Should Have) | Planned | | **MCP Tokens** | 5 | P1 (Should Have) | Planned | | **Tenant Management** | 4 | P0 (Must Have) | Planned | | **Total** | **24 features** | - | Day 1/10 Complete | --- ## Feature Categories ### Category 1: Multi-Tenancy Foundation (P0) **Business Value:** Enable SaaS business model, serve multiple customers on shared infrastructure | Feature ID | Feature Name | Description | Priority | |------------|--------------|-------------|----------| | MT-001 | Tenant Data Model | Tenant entity with subscription, limits, status | P0 | | MT-002 | Tenant Identification | JWT-based tenant resolution | P0 | | MT-003 | Data Isolation | Global Query Filter for automatic tenant filtering | P0 | | MT-004 | Tenant-Scoped Queries | All database queries filter by tenant_id | P0 | | MT-005 | Cross-Tenant Protection | Prevent access to other tenant's data | P0 | | MT-006 | Tenant Subdomain | Tenant-specific URLs (acme.colaflow.com) | P0 | ### Category 2: Authentication & Authorization (P0) **Business Value:** Secure access control, support enterprise identity providers | Feature ID | Feature Name | Description | Priority | |------------|--------------|-------------|----------| | AUTH-001 | JWT Authentication | JWT tokens with tenant claims | P0 | | AUTH-002 | Local Login | Email + password authentication | P0 | | AUTH-003 | Token Refresh | Automatic token refresh mechanism | P0 | | AUTH-004 | Logout | Clear authentication state | P0 | ### Category 3: SSO Integration (P1) **Business Value:** Enterprise requirement, reduces friction, improves security | Feature ID | Feature Name | Description | Priority | |------------|--------------|-------------|----------| | SSO-001 | OIDC Integration | Azure AD, Google, Okta support | P1 | | SSO-002 | SAML 2.0 Integration | Generic enterprise IdP support | P1 | | SSO-003 | User Auto-Provisioning | Create users on first SSO login | P1 | | SSO-004 | Domain Restrictions | Allow only specific email domains | P1 | | SSO-005 | SSO Configuration UI | Admin interface to configure SSO | P1 | ### Category 4: MCP Token Management (P1) **Business Value:** Enable AI agent integration, differentiate from competitors | Feature ID | Feature Name | Description | Priority | |------------|--------------|-------------|----------| | MCP-001 | Token Generation | Generate secure MCP tokens | P1 | | MCP-002 | Fine-Grained Permissions | Resource + operation level permissions | P1 | | MCP-003 | Token Revocation | Instant token revocation | P1 | | MCP-004 | Token Audit Logs | Complete audit trail of token usage | P1 | | MCP-005 | Token Management UI | UI to create, view, revoke tokens | P1 | ### Category 5: Tenant Management (P0) **Business Value:** Self-service onboarding, reduce support burden | Feature ID | Feature Name | Description | Priority | |------------|--------------|-------------|----------| | TM-001 | Tenant Registration | 3-step registration wizard | P0 | | TM-002 | Slug Validation | Real-time slug availability check | P0 | | TM-003 | Subscription Plans | Free, Starter, Pro, Enterprise plans | P0 | | TM-004 | Tenant Settings | Admin interface for tenant configuration | P0 | --- ## Detailed Feature Specifications ### MT-001: Tenant Data Model **Description:** Core tenant entity with all necessary attributes for multi-tenant operation **Functional Requirements:** - Tenant has unique ID (UUID) - Tenant has unique slug (URL-safe, 3-50 characters, lowercase, alphanumeric + hyphens) - Tenant has name (2-100 characters) - Tenant has status (Active, Suspended, Cancelled) - Tenant has subscription plan (Free, Starter, Professional, Enterprise) - Tenant has resource limits (max_users, max_projects, max_storage_gb) - Tenant has SSO configuration (JSONB, nullable) - Tenant has timestamps (created_at, updated_at, suspended_at) - Tenant has suspension reason (text, nullable) **Domain Model:** ```csharp public sealed class Tenant : AggregateRoot { public TenantId Id { get; private set; } public TenantName Name { get; private set; } public TenantSlug Slug { get; private set; } public TenantStatus Status { get; private set; } public SubscriptionPlan Plan { get; private set; } public SsoConfiguration? SsoConfig { get; private set; } // Resource limits public int MaxUsers { get; private set; } public int MaxProjects { get; private set; } public int MaxStorageGb { get; private set; } // Methods public static Tenant Create(TenantName name, TenantSlug slug, SubscriptionPlan plan); public void Activate(); public void Suspend(string reason); public void Cancel(); public void ConfigureSso(SsoConfiguration config); public void DisableSso(); public void UpgradePlan(SubscriptionPlan newPlan); } ``` **Acceptance Criteria:** - [ ] Tenant entity follows DDD aggregate root pattern - [ ] All business rules enforced at domain level - [ ] Value objects used for name, slug, SSO config - [ ] Domain events raised for all state changes - [ ] Unit tests cover all business logic (100% coverage) **Status:** COMPLETE (Day 1) --- ### MT-002: Tenant Identification **Description:** Resolve current tenant from JWT claims for all API requests **Functional Requirements:** - JWT access token contains tenant_id and tenant_slug claims - Middleware extracts tenant from JWT on every request - TenantContext service provides current tenant to application - Invalid or missing tenant results in 401 Unauthorized - Tenant status checked (suspended tenants cannot access API) **Technical Implementation:** ```csharp // JWT Claims { "sub": "user-id", "email": "john@acme.com", "tenant_id": "tenant-uuid", "tenant_slug": "acme", "tenant_plan": "Enterprise" } // TenantContext Service public class TenantContext { public TenantId CurrentTenantId { get; } public string CurrentTenantSlug { get; } public SubscriptionPlan CurrentTenantPlan { get; } } ``` **Acceptance Criteria:** - [ ] JWT contains tenant_id, tenant_slug, tenant_plan claims - [ ] Middleware extracts tenant from JWT successfully - [ ] TenantContext injected into all services - [ ] Missing tenant results in 401 error - [ ] Suspended tenant results in 403 error - [ ] Performance: <5ms overhead per request **Status:** PLANNED (Day 2) --- ### MT-003: Data Isolation **Description:** Automatic tenant filtering for all database queries using EF Core Global Query Filter **Functional Requirements:** - All entities have tenant_id column - EF Core Global Query Filter automatically adds `WHERE tenant_id = current_tenant` - Queries return only current tenant's data - Bypass requires explicit `.IgnoreQueryFilters()` (rare cases only) - Cross-tenant queries prevented at database level **Technical Implementation:** ```csharp protected override void OnModelCreating(ModelBuilder modelBuilder) { // Apply to all IHasTenant entities foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { if (typeof(IHasTenant).IsAssignableFrom(entityType.ClrType)) { modelBuilder.Entity(entityType.ClrType) .HasQueryFilter(BuildTenantFilter(entityType.ClrType)); } } } private LambdaExpression BuildTenantFilter(Type entityType) { var param = Expression.Parameter(entityType, "e"); var tenantIdProperty = Expression.Property(param, nameof(IHasTenant.TenantId)); var currentTenantId = Expression.Constant(_tenantContext.CurrentTenantId); var equals = Expression.Equal(tenantIdProperty, currentTenantId); return Expression.Lambda(equals, param); } ``` **Acceptance Criteria:** - [ ] Global Query Filter applied to all entities - [ ] All queries automatically filter by tenant - [ ] Cross-tenant queries return empty results - [ ] Integration tests verify tenant isolation - [ ] No database queries missing tenant filter (verified via logging) - [ ] Performance: Queries complete in <50ms with proper indexes **Status:** PLANNED (Day 2) --- ### MT-004: Tenant-Scoped Queries **Description:** Ensure all database queries respect tenant boundaries **Functional Requirements:** - All SELECT queries include `WHERE tenant_id = ?` - All INSERT queries include tenant_id column - All UPDATE/DELETE queries filter by tenant_id - Composite indexes on (tenant_id, other_columns) for performance - Unique constraints scoped to tenant (e.g., email unique per tenant) **Database Schema:** ```sql -- Example: Projects table CREATE TABLE projects ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, name VARCHAR(200) NOT NULL, key VARCHAR(20) NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT NOW(), CONSTRAINT uq_projects_tenant_key UNIQUE (tenant_id, key) ); CREATE INDEX idx_projects_tenant_id ON projects(tenant_id); CREATE INDEX idx_projects_tenant_key ON projects(tenant_id, key); ``` **Acceptance Criteria:** - [ ] All tables have tenant_id column (NOT NULL) - [ ] All queries include tenant_id filter - [ ] Composite indexes exist for all tenant-filtered queries - [ ] Unique constraints scoped to tenant - [ ] EXPLAIN ANALYZE shows index scans (not sequential scans) - [ ] Performance: Query time <50ms p95 **Status:** PLANNED (Day 2-4) --- ### MT-005: Cross-Tenant Protection **Description:** Prevent any cross-tenant data access (security feature) **Functional Requirements:** - Attempt to access other tenant's data returns 403 Forbidden - API validates tenant ownership before operations - Database constraints enforce tenant isolation - Integration tests verify cross-tenant protection - Audit logs track cross-tenant access attempts **Security Tests:** ```csharp [Fact] public async Task GetProject_WhenProjectBelongsToOtherTenant_Returns403() { // Arrange var tenantA = await CreateTenantAsync("acme"); var tenantB = await CreateTenantAsync("beta"); var projectInTenantA = await CreateProjectAsync(tenantA, "Project A"); // Act: Login as Tenant B, try to access Tenant A's project AuthenticateAs(tenantB); var response = await _client.GetAsync($"/api/projects/{projectInTenantA.Id}"); // Assert Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); } ``` **Acceptance Criteria:** - [ ] Cross-tenant GET requests return 403 Forbidden - [ ] Cross-tenant POST/PUT/DELETE requests return 403 Forbidden - [ ] Global Query Filter prevents cross-tenant reads - [ ] Repository methods validate tenant ownership - [ ] Security tests verify protection (10+ test cases) - [ ] Audit logs record cross-tenant attempts **Status:** PLANNED (Day 3-4, Day 8 security testing) --- ### MT-006: Tenant Subdomain **Description:** Each tenant has a unique subdomain (e.g., acme.colaflow.com) **Functional Requirements:** - Tenant slug used as subdomain (acme.colaflow.com) - Subdomain used for tenant resolution on login page - Subdomain displayed in tenant registration wizard - Subdomain availability checked in real-time - Reserved subdomains (www, api, admin, app, docs, etc.) prevented **User Experience:** ``` User visits: acme.colaflow.com/login ↓ System resolves tenant from subdomain ("acme") ↓ Login page displays: "Welcome to Acme Corp" ↓ User enters credentials ↓ JWT includes tenant_id and tenant_slug ↓ User redirected to: acme.colaflow.com/dashboard ``` **Acceptance Criteria:** - [ ] Subdomain resolves to tenant on login page - [ ] Tenant slug displayed in UI (e.g., "acme.colaflow.com") - [ ] Reserved subdomains rejected (www, api, admin, etc.) - [ ] Slug validation prevents invalid characters - [ ] Slug availability checked in real-time (debounced 500ms) **Status:** PLANNED (Day 5-6 frontend) --- ### AUTH-001: JWT Authentication **Description:** JWT-based stateless authentication with tenant claims **Functional Requirements:** - JWT access token: short-lived (60 minutes), contains user + tenant claims - JWT refresh token: long-lived (7 days), stored in httpOnly cookie - Access token used for API authentication (Authorization: Bearer header) - Refresh token used to obtain new access token - JWT signature validated on every request **JWT Structure:** ```json { "sub": "user-id-123", "email": "john@acme.com", "full_name": "John Doe", "tenant_id": "tenant-uuid-456", "tenant_slug": "acme", "tenant_plan": "Enterprise", "auth_provider": "Local", "role": "User", "exp": 1730678400, "iat": 1730674800, "iss": "colaflow-api", "aud": "colaflow-web" } ``` **Acceptance Criteria:** - [ ] JWT generated on successful login - [ ] Access token expires in 60 minutes - [ ] Refresh token expires in 7 days - [ ] JWT signature validated (HMAC SHA256) - [ ] Invalid JWT returns 401 Unauthorized - [ ] Expired JWT triggers automatic refresh - [ ] Middleware validates JWT on every request **Status:** PLANNED (Day 2-3) --- ### AUTH-002: Local Login **Description:** Email + password authentication (traditional login) **Functional Requirements:** - User enters email and password - System validates credentials - Password hashed with BCrypt (cost factor 12) - Failed login attempts throttled (max 5 attempts per 15 minutes) - Successful login generates JWT tokens - Login response includes user, tenant, and access token **API Contract:** ``` POST /api/auth/login Content-Type: application/json Request: { "email": "john@acme.com", "password": "SecurePassword123!" } Response (200 OK): { "user": { "id": "user-id", "email": "john@acme.com", "fullName": "John Doe" }, "tenant": { "id": "tenant-id", "slug": "acme", "name": "Acme Corp" }, "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } Set-Cookie: refreshToken=...; HttpOnly; Secure; SameSite=Strict; Max-Age=604800 ``` **Acceptance Criteria:** - [ ] Valid credentials return 200 OK with JWT - [ ] Invalid credentials return 401 Unauthorized - [ ] Password hashed with BCrypt (cost 12) - [ ] Failed login attempts throttled (max 5/15min) - [ ] Refresh token set in httpOnly cookie - [ ] Access token returned in response body **Status:** PLANNED (Day 3 backend, Day 5 frontend) --- ### AUTH-003: Token Refresh **Description:** Automatic token refresh mechanism to maintain user session **Functional Requirements:** - Frontend detects 401 error → calls refresh endpoint - Refresh endpoint validates refresh token (httpOnly cookie) - New access token generated and returned - Original request retried with new access token - Only one refresh in flight at a time (queue other requests) - Failed refresh → logout user **Flow:** ``` API Request with expired access token ↓ 401 Unauthorized Frontend intercepts error ↓ POST /api/auth/refresh (refresh token in cookie) ↓ 200 OK (new access token) Update Auth Store with new token ↓ Retry original request with new token ↓ 200 OK Return response to user ``` **Acceptance Criteria:** - [ ] 401 errors trigger automatic refresh - [ ] Refresh endpoint validates refresh token - [ ] New access token generated successfully - [ ] Original request retried with new token - [ ] Only one refresh call in flight (concurrent requests queued) - [ ] Failed refresh logs out user - [ ] Performance: Refresh completes in <500ms **Status:** PLANNED (Day 5 frontend API client) --- ### AUTH-004: Logout **Description:** Clear authentication state and invalidate tokens **Functional Requirements:** - User clicks logout button - Frontend clears Auth Store (user, tenant, accessToken) - Frontend calls logout endpoint (invalidates refresh token) - Backend clears refresh token cookie - User redirected to login page **API Contract:** ``` POST /api/auth/logout Response (200 OK): { "message": "Logged out successfully" } Set-Cookie: refreshToken=; HttpOnly; Secure; SameSite=Strict; Max-Age=0 (clear cookie) ``` **Acceptance Criteria:** - [ ] Logout clears frontend Auth Store - [ ] Logout clears refresh token cookie - [ ] User redirected to login page - [ ] Cross-tab logout (using storage events) - [ ] Subsequent API calls return 401 (no valid token) **Status:** PLANNED (Day 3 backend, Day 5 frontend) --- ### SSO-001: OIDC Integration **Description:** OpenID Connect (OIDC) integration for Azure AD, Google, Okta **Functional Requirements:** - Support Azure AD / Microsoft Entra - Support Google Workspace - Support Okta - Tenant admin configures SSO (Authority URL, Client ID, Client Secret) - OIDC discovery via .well-known/openid-configuration - State parameter for CSRF protection - User auto-provisioned on first SSO login **SSO Flow:** ``` User clicks "Sign in with Microsoft" ↓ Frontend calls: POST /api/auth/sso/initiate (provider: AzureAD) ↓ Backend generates state token (CSRF protection) Backend loads tenant's SSO config Backend builds authorization URL ↓ Redirect user to: https://login.microsoftonline.com/authorize?... ↓ User authenticates with Microsoft ↓ Microsoft redirects back to: /api/auth/sso/callback?code=xxx&state=yyy ↓ Backend validates state (CSRF check) Backend exchanges code for tokens (ID token + access token) Backend validates ID token signature ↓ Backend creates or updates user (auto-provision) Backend generates JWT with tenant claims ↓ Redirect user to: frontend/auth/callback?token=jwt ↓ Frontend stores JWT and redirects to dashboard ``` **Acceptance Criteria:** - [ ] OIDC login works with Azure AD - [ ] OIDC login works with Google - [ ] OIDC login works with Okta - [ ] State parameter validated (CSRF protection) - [ ] ID token signature validated - [ ] User auto-provisioned on first login - [ ] User profile updated from IdP claims - [ ] SSO errors handled gracefully (user-friendly messages) **Status:** PLANNED (Day 3-4 backend, Day 6 frontend) --- ### SSO-002: SAML 2.0 Integration **Description:** SAML 2.0 integration for generic enterprise IdPs **Functional Requirements:** - Support any SAML 2.0 compliant IdP - Tenant admin configures SAML (Entity ID, SSO URL, X.509 Certificate) - SAML assertion signature validated - SAML metadata endpoint for SP (Service Provider) - User auto-provisioned from SAML attributes **SAML Configuration:** ```json { "provider": "SAML", "entityId": "https://idp.acme.com/saml", "ssoUrl": "https://idp.acme.com/sso", "certificate": "-----BEGIN CERTIFICATE-----\nMIID...\n-----END CERTIFICATE-----", "metadataUrl": "https://idp.acme.com/metadata.xml" } ``` **Acceptance Criteria:** - [ ] SAML login works with generic IdP - [ ] SAML assertion signature validated - [ ] X.509 certificate validated - [ ] User auto-provisioned from SAML attributes (NameID, email, name) - [ ] SAML metadata endpoint exposed for SP - [ ] SAML errors handled gracefully **Status:** PLANNED (Day 4 backend, Day 6 frontend) --- ### SSO-003: User Auto-Provisioning **Description:** Automatically create user accounts on first SSO login **Functional Requirements:** - User does not exist in database → create new user - User attributes populated from IdP (email, name, avatar) - User linked to tenant based on SSO config - User marked as SSO user (auth_provider = AzureAD/Google/Okta/SAML) - External user ID stored (for future logins) **Auto-Provisioning Logic:** ```csharp public async Task AutoProvisionUserFromSsoAsync( TenantId tenantId, string externalUserId, string email, string fullName, AuthenticationProvider provider) { // Check if user already exists (by external_user_id) var existingUser = await _userRepository.GetByExternalUserIdAsync( tenantId, provider, externalUserId); if (existingUser != null) { // Update profile from IdP existingUser.UpdateProfile(email, fullName); return existingUser; } // Create new user var user = User.CreateFromSso( tenantId, Email.Create(email), FullName.Create(fullName), provider, externalUserId ); await _userRepository.AddAsync(user); return user; } ``` **Acceptance Criteria:** - [ ] New users created automatically on first SSO login - [ ] User email, name populated from IdP claims - [ ] User linked to correct tenant - [ ] External user ID stored for future logins - [ ] Existing users updated (profile sync) - [ ] Domain restrictions enforced (if configured) **Status:** PLANNED (Day 3-4 backend) --- ### SSO-004: Domain Restrictions **Description:** Restrict SSO login to specific email domains **Functional Requirements:** - Tenant admin can specify allowed email domains (e.g., @acme.com, @acme.co.uk) - SSO login checks user's email domain against allowed list - Unauthorized domain → login rejected with error message - Empty allowed domains list → all domains allowed **Configuration:** ```json { "provider": "AzureAD", "allowedDomains": ["acme.com", "acme.co.uk"], "autoProvision": true } ``` **Acceptance Criteria:** - [ ] Email domain validated against allowed list - [ ] Unauthorized domain returns error: "Your email domain is not allowed for SSO" - [ ] Empty allowed list allows all domains - [ ] Multiple domains supported - [ ] Case-insensitive domain matching **Status:** PLANNED (Day 3-4 backend, Day 6 frontend) --- ### SSO-005: SSO Configuration UI **Description:** Admin interface to configure SSO for tenant **Functional Requirements:** - Provider selection: Azure AD, Google, Okta, SAML 2.0 - Dynamic form fields based on provider: - OIDC: Authority URL, Client ID, Client Secret, Metadata URL - SAML: Entity ID, SSO URL, X.509 Certificate, Metadata URL - Auto-provision users toggle - Allowed email domains input (TagInput) - Test connection button (validates config) - Save configuration button - Display callback URL (for IdP configuration) **UI Screenshots:** See `docs/design/multi-tenant-ux-flows.md#sso-configuration-form` **Acceptance Criteria:** - [ ] Provider selection changes form fields - [ ] All fields validate correctly (required, format) - [ ] Test connection validates config (success/error with details) - [ ] Save configuration updates tenant SSO config - [ ] Callback URL displayed and copyable - [ ] Form accessible only to Admin users - [ ] Mobile responsive **Status:** PLANNED (Day 6 frontend) --- ### MCP-001: Token Generation **Description:** Generate secure MCP tokens for AI agents **Functional Requirements:** - Token format: `mcp__` - Token generated using CSPRNG (cryptographically secure random) - Token hashed with SHA256 before storage (never stored plain-text) - Token metadata: name, description, permissions, expiration - Token displayed only once after creation (security) **Token Generation:** ```csharp public string GenerateToken(string tenantSlug) { var randomBytes = new byte[16]; // 128 bits using var rng = RandomNumberGenerator.Create(); rng.GetBytes(randomBytes); var randomHex = Convert.ToHexString(randomBytes).ToLowerInvariant(); return $"mcp_{tenantSlug}_{randomHex}"; } public string HashToken(string token) { using var sha256 = SHA256.Create(); var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(token)); return Convert.ToBase64String(hashBytes); } ``` **Acceptance Criteria:** - [ ] Token format correct: `mcp__<32_hex>` - [ ] Token generated with CSPRNG (secure random) - [ ] Token hashed with SHA256 before storage - [ ] Token displayed only once (with warning) - [ ] Token metadata stored (name, permissions, expiration) - [ ] Copy and download options provided **Status:** PLANNED (Day 3-4 backend, Day 7 frontend) --- ### MCP-002: Fine-Grained Permissions **Description:** Resource-level + operation-level permissions for MCP tokens **Functional Requirements:** - Permissions stored as JSONB in database - Resources: Projects, Issues, Documents, Reports, Sprints, Comments - Operations: Read, Create, Update, Delete, Search - Permission checked on every API call - Unauthorized operation returns 403 Forbidden **Permission Structure:** ```json { "projects": ["read", "search"], "issues": ["read", "create", "update", "search"], "documents": ["read", "create", "search"], "reports": ["read"], "sprints": ["read", "search"], "comments": ["read", "create"] } ``` **Permission Check:** ```csharp public bool HasPermission(string resource, string operation) { if (!_permissions.ContainsKey(resource)) return false; return _permissions[resource].Contains(operation); } // Example usage if (!token.HasPermission("issues", "create")) { return Forbid("Token does not have permission to create issues"); } ``` **Acceptance Criteria:** - [ ] Permissions stored in JSONB format - [ ] All 6 resources supported - [ ] All 5 operations supported - [ ] Permission checked on every MCP API call - [ ] Unauthorized operation returns 403 Forbidden - [ ] Audit log records permission violations **Status:** PLANNED (Day 3-4 backend, Day 7 frontend) --- ### MCP-003: Token Revocation **Description:** Instant token revocation for security **Functional Requirements:** - Admin can revoke token at any time - Revoke updates token status to "Revoked" - Revoked token cannot be used (returns 401 Unauthorized) - Revocation reason recorded (optional) - Revocation timestamp recorded - Audit log entry created **Revocation Logic:** ```csharp public void Revoke(string reason) { if (Status == McpTokenStatus.Revoked) throw new DomainException("Token is already revoked"); Status = McpTokenStatus.Revoked; RevokedAt = DateTime.UtcNow; RevocationReason = reason; AddDomainEvent(new McpTokenRevokedEvent(Id, reason)); } ``` **Acceptance Criteria:** - [ ] Revoke button available on token details page - [ ] Revoke confirmation dialog shown - [ ] Revocation reason optional (text input) - [ ] Revoked token status updated immediately - [ ] Revoked token cannot be used (401 Unauthorized) - [ ] Audit log entry created - [ ] UI shows "Revoked" badge (red) **Status:** PLANNED (Day 3-4 backend, Day 7 frontend) --- ### MCP-004: Token Audit Logs **Description:** Complete audit trail of all MCP token operations **Functional Requirements:** - Every API call with MCP token logged - Audit log includes: timestamp, HTTP method, endpoint, request body, response status, duration, IP address, user agent - Audit logs stored in separate table (mcp_audit_logs) - Audit logs displayed on token details page - Audit logs filterable (date range, status code) - Audit logs exportable (CSV) **Audit Log Schema:** ```sql CREATE TABLE mcp_audit_logs ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, token_id UUID NOT NULL, user_id UUID NULL, http_method VARCHAR(10) NOT NULL, endpoint VARCHAR(500) NOT NULL, request_body TEXT NULL, status_code INT NOT NULL, response_body TEXT NULL, ip_address VARCHAR(50) NOT NULL, user_agent VARCHAR(500) NULL, timestamp TIMESTAMP NOT NULL DEFAULT NOW(), duration_ms INT NOT NULL, error_message TEXT NULL ); ``` **Acceptance Criteria:** - [ ] Every MCP API call logged - [ ] Audit log includes all required fields - [ ] Audit logs displayed on token details page - [ ] Pagination (50 logs per page) - [ ] Date range filter works - [ ] Status code filter works (200, 401, 403, 500) - [ ] Export to CSV works **Status:** PLANNED (Day 3-4 backend, Day 7 frontend) --- ### MCP-005: Token Management UI **Description:** User interface to create, view, and revoke MCP tokens **Functional Requirements:** - Token list page (table view) - Generate token button (opens 3-step wizard) - Token creation wizard: - Step 1: Token info (name, description, expiration) - Step 2: Permissions (matrix UI or templates) - Step 3: Review & create - Token display modal (one-time, with copy/download) - Token details page (metadata + audit logs) - Revoke token action (with confirmation) **UI Mockups:** See `docs/design/multi-tenant-ux-flows.md#mcp-token-management-flow` **Acceptance Criteria:** - [ ] Token list loads and displays all tokens - [ ] Generate token wizard works (3 steps) - [ ] Permission matrix or templates easy to use - [ ] Generated token displayed only once - [ ] Copy button works (toast notification) - [ ] Download button works (.env file) - [ ] Token details page shows metadata + audit logs - [ ] Revoke button works (with confirmation) - [ ] Mobile responsive **Status:** PLANNED (Day 7 frontend) --- ### TM-001: Tenant Registration **Description:** Self-service tenant registration with 3-step wizard **Functional Requirements:** - Step 1: Company information (name, slug) - Step 2: Administrator account (name, email, password) - Step 3: Subscription plan selection - Real-time slug validation (debounced 500ms) - Password strength indicator (weak/medium/strong) - Email verification (send email after registration) - Terms of service acceptance (checkbox) **Registration Flow:** See `docs/design/multi-tenant-ux-flows.md#tenant-registration-flow` **Acceptance Criteria:** - [ ] 3-step wizard navigates correctly - [ ] Step 1: Company name and slug validated - [ ] Slug availability checked in real-time - [ ] Slug suggestions shown if taken - [ ] Step 2: Email, password, name validated - [ ] Password strength indicator works - [ ] Step 3: Plan selection works - [ ] Registration creates tenant + admin user - [ ] User automatically logged in after registration - [ ] Welcome email sent - [ ] Mobile responsive **Status:** PLANNED (Day 3 backend, Day 5 frontend) --- ### TM-002: Slug Validation **Description:** Real-time slug availability check with suggestions **Functional Requirements:** - Slug validated on blur and debounced on typing (500ms) - Slug format: 3-50 characters, lowercase, alphanumeric + hyphens - Reserved slugs prevented (www, api, admin, app, dashboard, docs, blog, support, etc.) - Taken slugs show "Taken" message with suggestions - Available slugs show green checkmark **Validation Rules:** ```typescript // Format validation const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/; // Reserved slugs const reservedSlugs = [ 'www', 'api', 'admin', 'app', 'dashboard', 'docs', 'blog', 'support', 'status', 'legal' ]; // Suggestions if taken function suggestAlternatives(slug: string): string[] { return [ `${slug}-corp`, `${slug}-team`, `${slug}2` ]; } ``` **Acceptance Criteria:** - [ ] Slug format validated (regex) - [ ] Reserved slugs rejected - [ ] Availability checked via API - [ ] Real-time validation (debounced 500ms) - [ ] Green checkmark for available slug - [ ] Red X for taken slug with suggestions - [ ] Preview shows full domain (acme.colaflow.com) **Status:** PLANNED (Day 3 backend API, Day 5 frontend component) --- ### TM-003: Subscription Plans **Description:** Multiple subscription tiers with resource limits **Functional Requirements:** - 4 plans: Free, Starter, Professional, Enterprise - Each plan has limits: max_users, max_projects, max_storage_gb - Each plan has features (SSO, MCP tokens, support level) - Plan selection during registration (Step 3) - Plan upgrade/downgrade after registration (Settings page) **Plan Comparison:** | Feature | Free | Starter | Professional | Enterprise | |---------|------|---------|--------------|------------| | **Price** | $0/month | $19/month | $49/month | Custom | | **Users** | 5 | 15 | 50 | Unlimited | | **Projects** | 3 | 20 | 100 | Unlimited | | **Storage** | 2 GB | 10 GB | 100 GB | 1 TB+ | | **SSO** | No | No | Yes | Yes | | **MCP Tokens** | 3 | 10 | 50 | Unlimited | | **Support** | Community | Email | Priority | Dedicated | **Acceptance Criteria:** - [ ] 4 plans defined with limits - [ ] Plan selection UI during registration - [ ] Plan limits enforced (cannot exceed max_users, etc.) - [ ] Plan upgrade increases limits - [ ] Plan downgrade warns if limits exceeded - [ ] Free trial available for paid plans (14 days) **Status:** PLANNED (Day 1 domain model COMPLETE, Day 3 backend, Day 5 frontend) --- ### TM-004: Tenant Settings **Description:** Admin interface to manage tenant configuration **Functional Requirements:** - General settings: Name, slug (read-only), logo - SSO settings: Configure SSO (separate page) - Billing settings: Plan, payment method, invoices - Usage stats: Current users, projects, storage - Danger zone: Suspend tenant, cancel subscription **Settings Tabs:** - General - SSO (see SSO-005) - Billing - Usage **Acceptance Criteria:** - [ ] Settings page accessible to Admin users only - [ ] Tenant name editable - [ ] Logo upload works - [ ] Usage stats displayed correctly - [ ] Plan upgrade/downgrade works - [ ] Suspend tenant button works (with confirmation) - [ ] Cancel subscription works (with confirmation) **Status:** PLANNED (Day 3 backend, Day 6 frontend) --- ## Non-Functional Requirements ### Performance | Requirement | Target | Measurement | |-------------|--------|-------------| | **API Response Time** | <100ms (p95) | APM monitoring | | **Database Query Time** | <50ms (p95) | pg_stat_statements | | **Frontend Render Time** | <16ms (60fps) | React DevTools Profiler | | **Token Validation Time** | <10ms | Custom instrumentation | | **Page Load Time** | <1.5s | Lighthouse | | **Time to Interactive** | <3s | Lighthouse | ### Scalability | Requirement | Target | Notes | |-------------|--------|-------| | **Concurrent Users** | 10,000+ | Load testing with k6 | | **Tenants** | 10,000+ | Shared database model | | **API Requests** | 10,000/second | Horizontal scaling | | **Database Size** | 100+ GB | PostgreSQL with partitioning | | **Storage** | 10+ TB | S3 or equivalent | ### Reliability | Requirement | Target | SLA | |-------------|--------|-----| | **Uptime** | 99.9% | ~8 hours downtime/year | | **Error Rate** | <1% | Sentry monitoring | | **Data Loss** | 0% | Daily backups, replication | | **Recovery Time (RTO)** | <1 hour | Disaster recovery plan | | **Recovery Point (RPO)** | <5 minutes | Continuous replication | ### Security | Requirement | Standard | Verification | |-------------|----------|--------------| | **Authentication** | JWT + SSO | Security audit | | **Authorization** | RBAC + tenant isolation | Penetration testing | | **Data Encryption (Transit)** | TLS 1.3 | SSL Labs scan | | **Data Encryption (Rest)** | AES-256 | Database encryption | | **Password Hashing** | BCrypt (cost 12) | Code review | | **OWASP Top 10** | Compliant | Security testing | | **GDPR** | Compliant | Legal review | --- ## Technical Requirements ### Backend | Component | Technology | Version | Rationale | |-----------|------------|---------|-----------| | **Runtime** | .NET | 9.0 | Latest LTS | | **Language** | C# | 13.0 | Latest features | | **Database** | PostgreSQL | 16+ | JSON support, performance | | **ORM** | EF Core | 9.0 | Type-safe, migrations | | **API** | ASP.NET Core | 9.0 | Modern, fast | | **Auth** | ASP.NET Identity | 9.0 | Built-in SSO support | | **Validation** | FluentValidation | 11+ | Expressive validation | | **Testing** | xUnit | 2.6+ | Industry standard | ### Frontend | Component | Technology | Version | Rationale | |-----------|------------|---------|-----------| | **Framework** | Next.js | 16+ | App Router, SSR | | **Runtime** | React | 19+ | Latest features | | **Language** | TypeScript | 5.6+ | Type safety | | **State (Client)** | Zustand | 5+ | Lightweight, TypeScript-first | | **State (Server)** | TanStack Query | 5+ | Caching, mutations | | **Forms** | React Hook Form | 7+ | Performance, DX | | **Validation** | Zod | 3+ | TypeScript schemas | | **UI Components** | shadcn/ui | Latest | Accessible, customizable | | **Styling** | Tailwind CSS | 4+ | Utility-first | | **Testing** | Vitest | 2+ | Fast, Vite-based | ### Infrastructure | Component | Technology | Notes | |-----------|------------|-------| | **Hosting** | Vercel / AWS | Cloud-native | | **Database** | RDS PostgreSQL | Managed service | | **Storage** | S3 | Scalable, cheap | | **CDN** | CloudFront | Global distribution | | **Monitoring** | Sentry + DataDog | Error tracking + APM | | **CI/CD** | GitHub Actions | Automated deployments | --- ## Security Requirements ### Authentication Security - [ ] Passwords hashed with BCrypt (cost factor 12) - [ ] Failed login attempts throttled (max 5 per 15 minutes) - [ ] JWT tokens signed with HMAC SHA256 (512-bit secret) - [ ] Access tokens short-lived (60 minutes) - [ ] Refresh tokens long-lived (7 days) in httpOnly cookies - [ ] Token refresh requires valid refresh token - [ ] Logout invalidates refresh token ### Authorization Security - [ ] All API endpoints require authentication (except login, registration) - [ ] Tenant isolation enforced at database level (Global Query Filter) - [ ] Cross-tenant access attempts logged and blocked (403 Forbidden) - [ ] Admin-only endpoints check user role - [ ] MCP token permissions checked on every operation - [ ] Permission violations logged in audit log ### Data Security - [ ] All data encrypted in transit (TLS 1.3) - [ ] All data encrypted at rest (AES-256) - [ ] Database backups encrypted - [ ] Sensitive fields (passwords, tokens) never logged - [ ] PII (personally identifiable information) minimized - [ ] GDPR compliance (data export, deletion) ### SSO Security - [ ] State parameter used for CSRF protection (OIDC) - [ ] SAML assertion signature validated - [ ] X.509 certificate validated (SAML) - [ ] ID token signature validated (OIDC) - [ ] SSO configuration stored encrypted (Client Secret) - [ ] Email domain restrictions enforced ### MCP Token Security - [ ] Tokens generated with CSPRNG (cryptographically secure random) - [ ] Tokens hashed with SHA256 before storage - [ ] Tokens never stored plain-text - [ ] Tokens displayed only once (after creation) - [ ] Revoked tokens invalid immediately - [ ] Token usage logged in audit trail - [ ] Rate limiting applied to MCP endpoints ### OWASP Top 10 Compliance - [ ] **A01:2021 – Broken Access Control:** Tenant isolation + RBAC enforced - [ ] **A02:2021 – Cryptographic Failures:** TLS 1.3 + AES-256 encryption - [ ] **A03:2021 – Injection:** Parameterized queries (EF Core) - [ ] **A04:2021 – Insecure Design:** Security-first architecture - [ ] **A05:2021 – Security Misconfiguration:** Secure defaults, config reviews - [ ] **A06:2021 – Vulnerable Components:** Dependency scanning (Dependabot) - [ ] **A07:2021 – Auth Failures:** JWT + SSO + MFA (future) - [ ] **A08:2021 – Software Integrity:** Code signing, SRI - [ ] **A09:2021 – Logging Failures:** Comprehensive audit logs - [ ] **A10:2021 – SSRF:** Input validation, URL whitelisting --- ## Acceptance Criteria Matrix ### Feature Completion Checklist | Feature ID | Feature Name | Backend | Frontend | Tests | Docs | Status | |------------|--------------|---------|----------|-------|------|--------| | MT-001 | Tenant Data Model | DONE | N/A | DONE | DONE | COMPLETE | | MT-002 | Tenant Identification | Planned | Planned | Planned | Planned | Pending | | MT-003 | Data Isolation | Planned | N/A | Planned | Planned | Pending | | MT-004 | Tenant-Scoped Queries | Planned | N/A | Planned | Planned | Pending | | MT-005 | Cross-Tenant Protection | Planned | N/A | Planned | Planned | Pending | | MT-006 | Tenant Subdomain | Planned | Planned | Planned | Planned | Pending | | AUTH-001 | JWT Authentication | Planned | Planned | Planned | Planned | Pending | | AUTH-002 | Local Login | Planned | Planned | Planned | Planned | Pending | | AUTH-003 | Token Refresh | Planned | Planned | Planned | Planned | Pending | | AUTH-004 | Logout | Planned | Planned | Planned | Planned | Pending | | SSO-001 | OIDC Integration | Planned | Planned | Planned | Planned | Pending | | SSO-002 | SAML 2.0 Integration | Planned | Planned | Planned | Planned | Pending | | SSO-003 | User Auto-Provisioning | Planned | N/A | Planned | Planned | Pending | | SSO-004 | Domain Restrictions | Planned | Planned | Planned | Planned | Pending | | SSO-005 | SSO Configuration UI | N/A | Planned | Planned | Planned | Pending | | MCP-001 | Token Generation | Planned | Planned | Planned | Planned | Pending | | MCP-002 | Fine-Grained Permissions | Planned | Planned | Planned | Planned | Pending | | MCP-003 | Token Revocation | Planned | Planned | Planned | Planned | Pending | | MCP-004 | Token Audit Logs | Planned | Planned | Planned | Planned | Pending | | MCP-005 | Token Management UI | N/A | Planned | Planned | Planned | Pending | | TM-001 | Tenant Registration | Planned | Planned | Planned | Planned | Pending | | TM-002 | Slug Validation | Planned | Planned | Planned | Planned | Pending | | TM-003 | Subscription Plans | DONE | Planned | DONE | Planned | Partial | | TM-004 | Tenant Settings | Planned | Planned | Planned | Planned | Pending | **Overall Progress:** 1/24 features complete (4.2%) **Day 1 Progress:** 10% of backend foundation complete --- ## Appendix: Related Documentation ### Architecture Documents - `docs/architecture/multi-tenancy-architecture.md` - Multi-tenant design - `docs/architecture/sso-integration-architecture.md` - SSO implementation - `docs/architecture/mcp-authentication-architecture.md` - MCP token system - `docs/architecture/jwt-authentication-architecture.md` - JWT with tenant claims - `docs/architecture/migration-strategy.md` - Database migration plan ### Design Documents - `docs/design/multi-tenant-ux-flows.md` - Complete user flows - `docs/design/ui-component-specs.md` - 16 component specifications - `docs/design/responsive-design-guide.md` - Responsive breakpoints - `docs/design/design-tokens.md` - Design system tokens ### Implementation Documents - `docs/frontend/implementation-plan.md` - 4-day development plan - `docs/frontend/api-integration-guide.md` - API client + endpoints - `docs/frontend/state-management-guide.md` - Zustand + TanStack Query - `docs/frontend/component-library.md` - Component implementations --- **Document Status:** Approved for Development **Next Review:** Day 4 (2025-11-06) - Post Backend Completion Review **Owner:** Product Manager **Approval Date:** 2025-11-03 --- **End of M1.2 Feature List**