43 KiB
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
- Feature Overview
- Feature Categories
- Detailed Feature Specifications
- Non-Functional Requirements
- Technical Requirements
- Security Requirements
- Acceptance Criteria Matrix
Feature Overview
M1.2 Goals
- Multi-Tenancy: Support multiple companies (tenants) on shared infrastructure
- SSO Integration: Enable enterprise SSO (Azure AD, Google, Okta, SAML 2.0)
- MCP Authentication: Secure AI agent access via MCP tokens
- Tenant Management: Self-service tenant registration and administration
- 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:
public sealed class Tenant : AggregateRoot<TenantId>
{
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:
// 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:
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:
-- 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:
[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:
{
"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:
{
"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:
public async Task<User> 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:
{
"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_<tenant_slug>_<random_32_hex> - 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:
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_<slug>_<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:
{
"projects": ["read", "search"],
"issues": ["read", "create", "update", "search"],
"documents": ["read", "create", "search"],
"reports": ["read"],
"sprints": ["read", "search"],
"comments": ["read", "create"]
}
Permission Check:
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:
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:
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:
// 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 | 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 designdocs/architecture/sso-integration-architecture.md- SSO implementationdocs/architecture/mcp-authentication-architecture.md- MCP token systemdocs/architecture/jwt-authentication-architecture.md- JWT with tenant claimsdocs/architecture/migration-strategy.md- Database migration plan
Design Documents
docs/design/multi-tenant-ux-flows.md- Complete user flowsdocs/design/ui-component-specs.md- 16 component specificationsdocs/design/responsive-design-guide.md- Responsive breakpointsdocs/design/design-tokens.md- Design system tokens
Implementation Documents
docs/frontend/implementation-plan.md- 4-day development plandocs/frontend/api-integration-guide.md- API client + endpointsdocs/frontend/state-management-guide.md- Zustand + TanStack Querydocs/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