Skip to main content

Multi-Tenant Isolation

STOA implements a hard multi-tenancy model where each tenant is fully isolated across infrastructure, identity, data, and networking layers. This enables a single STOA deployment to serve multiple organizations without cross-tenant data leakage.

Tenant Data Model​

Each tenant in STOA has the following properties:

FieldTypeDescription
idstringSlug identifier (e.g., oasis, acme-corp) β€” immutable
namestringDisplay name (e.g., "OASIS Gunters")
descriptionstringOptional description
statusenumactive, suspended, archived
settingsJSONQuotas, feature flags, custom config
created_attimestampCreation date

Tenant Status Lifecycle​

  • Active β€” Full access to all platform features
  • Suspended β€” Read-only access, no API calls, no deployments. Used for billing issues or compliance holds.
  • Archived β€” Data retained for audit, no access. Pending deletion per retention policy.

Five Isolation Layers​

1. Kubernetes Namespace Isolation​

Each tenant operates in a dedicated namespace with labels for policy enforcement:

apiVersion: v1
kind: Namespace
metadata:
name: tenant-acme
labels:
stoa.io/tenant-id: acme
stoa.io/tier: enterprise
pod-security.kubernetes.io/enforce: restricted

Resource quotas prevent a single tenant from consuming cluster resources:

apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: tenant-acme
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
persistentvolumeclaims: "5"
services.loadbalancers: "2"

2. Network Isolation​

Network policies prevent cross-tenant communication at the CNI level:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tenant-isolation
namespace: tenant-acme
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
ingress:
- from:
- namespaceSelector:
matchLabels:
stoa.io/tenant-id: acme
egress:
- to:
- namespaceSelector:
matchLabels:
stoa.io/tenant-id: acme
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: stoa-system

Tenants can communicate with their own namespace and the shared stoa-system namespace (for the Control Plane API and Gateway), but never with other tenants.

3. Gateway Isolation​

The STOA Gateway enforces tenant boundaries at the API layer:

  • Tenant-scoped routing β€” Each API is scoped to a tenant ID
  • Separate rate limits β€” Per-tenant quota enforcement
  • Independent policies β€” OPA policies evaluate tenant context
  • Tenant-specific certificates β€” mTLS certificates scoped per tenant

In multi-gateway deployments, each gateway adapter (Kong, Gravitee, webMethods, STOA) maintains tenant isolation through its native mechanisms.

4. Authentication Isolation​

Keycloak multi-realm architecture provides identity isolation:

  • One realm per tenant β€” Isolated user stores, separate credentials
  • Isolated client configurations β€” Each tenant has its own OIDC clients
  • Independent token validation β€” Tokens from one realm are invalid in another
  • Tenant-scoped roles β€” tenant-admin can only manage their own tenant

5. Data Isolation​

  • Schema-per-tenant β€” Database schemas isolated per tenant
  • Encrypted at rest β€” All tenant data encrypted (AES-256)
  • Separate backup policies β€” Per-tenant backup schedules
  • Audit logging β€” Every data access logged with tenant context

RBAC and Tenant Scoping​

STOA's RBAC model combines platform-wide and tenant-scoped roles:

RoleScopePermissions
cpi-adminPlatformFull access to all tenants, all operations
tenant-adminTenantFull access to own tenant only
devopsTenantDeploy and promote within own tenant
viewerTenantRead-only access to own tenant

Key behaviors:

  • A tenant-admin for tenant acme cannot see tenant globex resources
  • A viewer can browse APIs and tools but cannot invoke, create, or modify
  • A cpi-admin sees all tenants and can perform cross-tenant operations
  • Environment mode (dev/staging/prod) further restricts operations β€” production is read-only by default

Tenant Settings​

The settings JSON field on each tenant allows per-tenant configuration:

{
"quotas": {
"max_apis": 50,
"max_subscriptions": 200,
"max_rate_limit": 10000
},
"features": {
"mcp_enabled": true,
"shadow_mode": false,
"advanced_analytics": true
},
"notifications": {
"webhook_url": "https://hooks.acme.com/stoa",
"email_alerts": true
}
}

Tenant Tiers​

TierResourcesFeaturesSLA
CommunityLimitedCore APIs, basic MCPBest effort
StarterModerateAPIs + MCP tools, portal99%
BusinessHighFull platform, multi-gatewayPer agreement
EnterpriseCustomWhite-label, dedicated supportCustom SLA

Per-Tenant Observability​

Every metric in STOA is labeled with the tenant ID, enabling per-tenant dashboards:

  • API request rates β€” stoa_api_requests_total{tenant="acme"}
  • Error rates β€” stoa_api_errors_total{tenant="acme"}
  • Latency percentiles β€” stoa_api_duration_seconds{tenant="acme"}
  • Resource utilization β€” CPU, memory, storage per namespace
  • Cost attribution β€” Per-tenant resource consumption for billing

Grafana dashboards can be filtered by tenant for tenant-admins, or viewed across all tenants for platform admins.