# 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<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:**
```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<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:**
```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_<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:**
```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_<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:**
```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**
