> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hopx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-Tenant Code Execution Platform

> Build a SaaS platform with custom code execution featuring tenant isolation, resource quotas, security boundaries, and billing integration

Build a production-ready multi-tenant code execution platform for SaaS applications. This cookbook demonstrates how to create a platform with tenant isolation, resource quotas, and security boundaries using HopX.

## Overview

Multi-tenant platforms serve multiple customers (tenants) on shared infrastructure. Each tenant's code must be completely isolated, resources must be quota-limited, and security boundaries must be enforced.

## Prerequisites

* HopX API key ([Get one here](https://console.hopx.dev/api-keys))
* Python 3.8+ or Node.js 16+
* Understanding of multi-tenant architecture
* Basic knowledge of resource quotas

## Architecture

```
┌──────────────┐
│  Tenant A    │ Code execution
└──────┬───────┘
       │
       ▼
┌─────────────────┐
│  Tenant         │ Isolate, quota
│   Manager       │
└──────┬──────────┘
       │
       ▼
┌─────────────────┐
│  Tenant         │ Isolated sandbox
│  Sandbox A      │
└─────────────────┘
```

## Implementation

### Step 1: Tenant Isolation

Ensure complete tenant isolation:

<CodeGroup>
  ```python Python theme={null}
  from hopx_ai import Sandbox
  import os
  from typing import Dict, Any

  class Tenant:
      def __init__(self, tenant_id: str, quota: Dict[str, int]):
          self.tenant_id = tenant_id
          self.quota = quota  # {"executions_per_hour": 100, "max_execution_time": 60}

  class MultiTenantPlatform:
      def __init__(self, api_key: str):
          self.api_key = api_key
          self.tenants = {}
          self.tenant_sandboxes = {}
          self.usage_tracking = {}
      
      def register_tenant(self, tenant: Tenant):
          """Register a tenant"""
          self.tenants[tenant.tenant_id] = tenant
          self.usage_tracking[tenant.tenant_id] = {
              "executions": 0,
              "execution_time": 0
          }
      
      def execute_for_tenant(self, tenant_id: str, code: str) -> Dict[str, Any]:
          """Execute code for specific tenant"""
          if tenant_id not in self.tenants:
              return {
                  "success": False,
                  "error": f"Tenant {tenant_id} not found"
              }
          
          tenant = self.tenants[tenant_id]
          usage = self.usage_tracking[tenant_id]
          
          # Check quota
          if usage["executions"] >= tenant.quota.get("executions_per_hour", 100):
              return {
                  "success": False,
                  "error": "Execution quota exceeded"
              }
          
          sandbox = None
          try:
              # Create or get tenant sandbox (isolated per tenant)
              if tenant_id not in self.tenant_sandboxes:
                  self.tenant_sandboxes[tenant_id] = Sandbox.create(
                      template="code-interpreter",
                      api_key=self.api_key,
                      timeout_seconds=tenant.quota.get("max_execution_time", 60)
                  )
              
              sandbox = self.tenant_sandboxes[tenant_id]
              
              # Set tenant context
              sandbox.env.set("TENANT_ID", tenant_id)
              
              # Execute code
              result = sandbox.run_code(code, timeout=tenant.quota.get("max_execution_time", 60))
              
              # Update usage
              usage["executions"] += 1
              usage["execution_time"] += result.execution_time
              
              return {
                  "success": result.success,
                  "stdout": result.stdout,
                  "stderr": result.stderr,
                  "tenant_id": tenant_id,
                  "usage": usage
              }
          except Exception as e:
              return {
                  "success": False,
                  "error": str(e),
                  "tenant_id": tenant_id
              }
      
      def get_tenant_usage(self, tenant_id: str) -> Dict[str, Any]:
          """Get tenant usage statistics"""
          if tenant_id not in self.usage_tracking:
              return {"error": "Tenant not found"}
          
          return self.usage_tracking[tenant_id]
      
      def cleanup_tenant(self, tenant_id: str):
          """Clean up tenant resources"""
          if tenant_id in self.tenant_sandboxes:
              self.tenant_sandboxes[tenant_id].kill()
              del self.tenant_sandboxes[tenant_id]

  # Usage
  platform = MultiTenantPlatform(api_key=os.getenv("HOPX_API_KEY"))

  # Register tenants
  platform.register_tenant(Tenant("tenant_1", {"executions_per_hour": 100, "max_execution_time": 60}))
  platform.register_tenant(Tenant("tenant_2", {"executions_per_hour": 200, "max_execution_time": 120}))

  # Execute for tenant
  result = platform.execute_for_tenant("tenant_1", "print('Hello from tenant 1')")
  print(result)

  usage = platform.get_tenant_usage("tenant_1")
  print(usage)
  ```

  ```javascript JavaScript theme={null}
  import { Sandbox } from '@hopx-ai/sdk';

  class Tenant {
      constructor(tenantId, quota) {
          this.tenantId = tenantId;
          this.quota = quota;  // {executionsPerHour: 100, maxExecutionTime: 60}
      }
  }

  class MultiTenantPlatform {
      constructor(apiKey) {
          this.apiKey = apiKey;
          this.tenants = {};
          this.tenantSandboxes = {};
          this.usageTracking = {};
      }
      
      registerTenant(tenant) {
          this.tenants[tenant.tenantId] = tenant;
          this.usageTracking[tenant.tenantId] = {
              executions: 0,
              executionTime: 0
          };
      }
      
      async executeForTenant(tenantId, code) {
          if (!this.tenants[tenantId]) {
              return {
                  success: false,
                  error: `Tenant ${tenantId} not found`
              };
          }
          
          const tenant = this.tenants[tenantId];
          const usage = this.usageTracking[tenantId];
          
          // Check quota
          if (usage.executions >= (tenant.quota.executionsPerHour || 100)) {
              return {
                  success: false,
                  error: 'Execution quota exceeded'
              };
          }
          
          try {
              // Create or get tenant sandbox (isolated per tenant)
              if (!this.tenantSandboxes[tenantId]) {
                  this.tenantSandboxes[tenantId] = await Sandbox.create({
                      template: 'code-interpreter',
                      apiKey: this.apiKey,
                      timeoutSeconds: tenant.quota.maxExecutionTime || 60
                  });
              }
              
              const sandbox = this.tenantSandboxes[tenantId];
              
              // Set tenant context
              await sandbox.env.set('TENANT_ID', tenantId);
              
              // Execute code
              const result = await sandbox.runCode(code, {
                  timeout: tenant.quota.maxExecutionTime || 60
              });
              
              // Update usage
              usage.executions += 1;
              usage.executionTime += result.execution_time || 0;
              
              return {
                  success: result.success,
                  stdout: result.stdout,
                  stderr: result.stderr,
                  tenantId,
                  usage
              };
          } catch (error) {
              return {
                  success: false,
                  error: error.message,
                  tenantId
              };
          }
      }
      
      getTenantUsage(tenantId) {
          if (!this.usageTracking[tenantId]) {
              return { error: 'Tenant not found' };
          }
          
          return this.usageTracking[tenantId];
      }
      
      async cleanupTenant(tenantId) {
          if (this.tenantSandboxes[tenantId]) {
              await this.tenantSandboxes[tenantId].kill();
              delete this.tenantSandboxes[tenantId];
          }
      }
  }

  // Usage
  const platform = new MultiTenantPlatform(process.env.HOPX_API_KEY);

  // Register tenants
  platform.registerTenant(new Tenant('tenant_1', { executionsPerHour: 100, maxExecutionTime: 60 }));
  platform.registerTenant(new Tenant('tenant_2', { executionsPerHour: 200, maxExecutionTime: 120 }));

  // Execute for tenant
  const result = await platform.executeForTenant('tenant_1', "print('Hello from tenant 1')");
  console.log(result);

  const usage = platform.getTenantUsage('tenant_1');
  console.log(usage);
  ```
</CodeGroup>

## Best Practices

1. **Complete Isolation**: One sandbox per tenant
2. **Resource Quotas**: Enforce strict quotas
3. **Security Boundaries**: Maintain security between tenants
4. **Usage Tracking**: Track usage for billing

## Related Cookbooks

* [Plugin System](/cookbooks/marketplace/plugin-system) - Plugin isolation
* [Low-Code Platform Backend](/cookbooks/enterprise/low-code-backend) - Enterprise platforms

## Next Steps

1. Implement billing integration
2. Add tenant management UI
3. Create usage analytics
4. Implement quota enforcement
5. Add tenant onboarding
