Skip to content

Multi-Tenant Enterprise Authorization Support #53

@jdutton

Description

@jdutton

Multi-Tenant Enterprise Authorization Support

Overview

Add comprehensive multi-tenant enterprise authorization capabilities to enable organizations to deploy the MCP server with tenant isolation, role-based access control, and enterprise SSO integration.

Problem Statement

The current OAuth implementation supports multi-provider authentication (Google, GitHub, Microsoft) and has distributed state management via Redis PKCE stores, but lacks:

  1. Tenant Isolation - All users share the same MCP server instance with no organizational boundaries
  2. Organization/Workspace Model - No concept of teams, workspaces, or hierarchical access control
  3. Tenant-Scoped OAuth - Single OAuth configuration for entire deployment; cannot configure per-tenant OAuth apps
  4. Enterprise SSO - No SAML 2.0, OIDC federation, or Azure AD B2C multi-tenant support
  5. RBAC - No role-based access control or fine-grained permissions
  6. Tenant Administration - No provisioning, quotas, usage tracking, or billing capabilities

Proposed Solution

Implement a comprehensive multi-tenant authorization system with the following phases:

Phase 1: Tenant Data Model (Foundation)

Core Entities

interface Tenant {
  tenantId: string;
  organizationName: string;
  domain?: string;
  status: 'active' | 'suspended' | 'trial';
  plan: 'free' | 'pro' | 'enterprise';
  settings: TenantSettings;
  createdAt: number;
  updatedAt: number;
}

interface TenantSettings {
  oauth?: {
    google?: TenantOAuthConfig;
    github?: TenantOAuthConfig;
    microsoft?: TenantOAuthConfig;
    saml?: SAMLConfig;
  };
  allowlist?: string[];
  domains?: string[];
  quotas?: TenantQuotas;
  features?: FeatureFlags;
}

interface TenantUser {
  userId: string;
  email: string;
  role: 'owner' | 'admin' | 'member' | 'readonly';
  joinedAt: number;
}

Tenant Store Interface

interface TenantStore {
  // CRUD
  createTenant(tenant: Tenant): Promise<void>;
  getTenant(tenantId: string): Promise<Tenant | null>;
  getTenantByDomain(domain: string): Promise<Tenant | null>;
  updateTenant(tenantId: string, updates: Partial<Tenant>): Promise<void>;
  deleteTenant(tenantId: string): Promise<void>;
  
  // User-tenant associations
  addUserToTenant(tenantId: string, userId: string, role: string): Promise<void>;
  removeUserFromTenant(tenantId: string, userId: string): Promise<void>;
  getUserTenants(userId: string): Promise<string[]>;
  getTenantUsers(tenantId: string): Promise<TenantUser[]>;
  
  listTenants(options?: ListOptions): Promise<Tenant[]>;
}

Tenant Resolution

  • Subdomain-based: tenant1.yourapp.com
  • Header-based: X-Tenant-ID header
  • Token-embedded: Tenant ID in OAuth token claims

Phase 2: Tenant-Scoped OAuth

Multi-Tenant OAuth Provider

  • Per-tenant OAuth credentials (client ID, secret, redirect URI)
  • Tenant-specific scopes and configuration
  • Support for multiple OAuth apps per provider type
  • Tenant resolution in OAuth flows

Token Storage Updates

interface StoredTokenInfo {
  accessToken: string;
  // ... existing fields
  tenantId: string;  // NEW: Tenant isolation
}

interface OAuthTokenStore {
  storeToken(tenantId: string, token: string, info: StoredTokenInfo): Promise<void>;
  getToken(tenantId: string, token: string): Promise<StoredTokenInfo | null>;
  // ... tenant-scoped methods
}

Phase 3: RBAC & Authorization

Role-Based Access Control

interface Role {
  roleId: string;
  name: string;
  tenantId: string;
  permissions: Permission[];
}

interface Permission {
  resource: string;      // e.g., 'tools', 'sessions', 'users'
  action: string;        // e.g., 'read', 'write', 'delete'
  conditions?: Record<string, any>;
}

Authorization Checks

  • Tool execution authorization
  • Resource access control
  • Tenant-scoped data isolation
  • User role verification

Phase 4: Enterprise SSO Integration

SAML 2.0 Support

interface SAMLConfig {
  entryPoint: string;           // IdP SSO URL
  issuer: string;               // SP entity ID
  cert: string;                 // IdP certificate
  callbackUrl: string;          // SP callback URL
  identifierFormat?: string;
  signatureAlgorithm?: string;
}

Azure AD B2C Multi-Tenant

  • B2C tenant configuration
  • Policy-based authentication
  • Multi-tenant claim resolution
  • Domain verification

Okta/Auth0 Integration

  • Workforce identity integration
  • Organization-based routing
  • Custom domain support

Phase 5: Tenant Administration & Monitoring

Admin API Endpoints

POST   /admin/tenants                    - Create tenant
GET    /admin/tenants/:id                - Get tenant details
PATCH  /admin/tenants/:id                - Update tenant
DELETE /admin/tenants/:id                - Delete tenant

POST   /admin/tenants/:id/users          - Add user to tenant
DELETE /admin/tenants/:id/users/:userId  - Remove user
GET    /admin/tenants/:id/users          - List tenant users

PATCH  /admin/tenants/:id/oauth          - Update OAuth config
PATCH  /admin/tenants/:id/features       - Update feature flags
PATCH  /admin/tenants/:id/quotas         - Update quotas

GET    /admin/tenants/:id/usage          - Get usage metrics
GET    /admin/tenants/:id/sessions       - Get active sessions
GET    /admin/tenants/:id/audit-log      - Get audit trail

Usage Tracking & Quotas

interface TenantQuotas {
  maxUsers: number;
  maxSessionsPerUser: number;
  rateLimit: {
    requestsPerMinute: number;
    requestsPerDay: number;
  };
}

class TenantUsageTracker {
  trackRequest(tenantId: string, userId: string): Promise<void>;
  checkQuota(tenantId: string, userId: string): Promise<boolean>;
  getUsageReport(tenantId: string, period: string): Promise<UsageReport>;
}

Implementation Considerations

Backward Compatibility

  • Existing single-tenant deployments continue working
  • Opt-in via MULTI_TENANT_MODE=enabled environment variable
  • Migrate existing users to default "system" tenant
  • Graceful fallback for non-tenant-aware clients

Database Schema

  • Tenant table with settings (JSONB column for flexibility)
  • Tenant-user association table with roles
  • Tenant-scoped indexes for all resource tables
  • Migration scripts for existing data

Performance

  • Tenant resolution caching (Redis)
  • Tenant settings caching
  • Index optimization for tenant-scoped queries
  • Connection pooling per tenant (if needed)

Security

  • Tenant data isolation at database level
  • Row-level security policies
  • Tenant context validation in all API calls
  • Audit logging for cross-tenant access attempts

Migration Path

Step 1: Add Tenant Infrastructure (Non-Breaking)

  • Implement Tenant entity and TenantStore interface
  • Add RedisTenantStore implementation
  • Add tenant resolution middleware (optional/disabled by default)
  • Estimated: 2-3 weeks

Step 2: Opt-In Tenant Features

  • Allow existing deployments to continue as single-tenant
  • Add MULTI_TENANT_MODE flag
  • Default tenant creation and migration
  • Estimated: 1 week

Step 3: Tenant-Scoped OAuth

  • Update OAuth providers with tenant context
  • Per-tenant OAuth configuration
  • Backward compatibility with global config
  • Estimated: 2 weeks

Step 4: RBAC & Enterprise Features

  • Role-based access control implementation
  • SAML/enterprise SSO support
  • Permission checking middleware
  • Estimated: 3-4 weeks

Step 5: Administration & Monitoring

  • Tenant admin APIs
  • Usage tracking and quotas
  • Audit logging
  • Tenant provisioning workflows
  • Estimated: 2-3 weeks

Total Estimated Effort: 10-13 weeks

Success Criteria

  • Multiple tenants can operate in isolation on same deployment
  • Each tenant can configure their own OAuth providers
  • Users can belong to multiple tenants with different roles
  • Enterprise SSO (SAML 2.0) integration works
  • Admin can provision/deprovision tenants via API
  • Usage tracking and quota enforcement functional
  • Backward compatibility maintained for single-tenant deployments
  • Performance impact < 10% for tenant resolution overhead
  • Complete audit trail for tenant operations
  • Documentation and migration guides complete

Alternative Approaches

1. Separate Deployment Per Tenant

Pros: Complete isolation, simpler architecture
Cons: Higher operational overhead, resource waste, harder to manage

2. Tenant-Aware Database (Postgres RLS)

Pros: Database-level isolation, less application logic
Cons: Postgres-specific, harder to migrate, limited flexibility

3. External IAM Service (Auth0, Okta)

Pros: Offload complexity, proven solution
Cons: Vendor lock-in, additional cost, integration complexity

Related Issues

References


Labels: enhancement, enterprise, oauth, multi-tenant, architecture
Priority: Medium (future enhancement)
Complexity: High
Breaking Change: No (backward compatible)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions