Multi-Tenancy Models and Isolation Strategies
Overview
Prism is designed to support multiple tenancy models with configurable component isolation at the proxy level. This flexibility allows organizations to choose the right balance between resource efficiency, performance isolation, security boundaries, and operational complexity based on their specific requirements.
This memo explores three primary tenancy models and three isolation levels, providing guidance on when to use each approach and how to configure Prism accordingly.
Tenancy Models
1. Single Tenancy (Self-Managed)
Architecture: One proxy deployment per tenant, fully isolated infrastructure.
┌─────────────────────────────────────────────────────┐
│ Tenant A (Large Enterprise Application) │
│ │
│ ┌───────── ─────────────────────────────────┐ │
│ │ Prism Proxy Cluster (N-way deployment) │ │
│ │ │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │Proxy-1 │ │Proxy-2 │ │Proxy-N │ │ │
│ │ └────────┘ └────────┘ └────────┘ │ │
│ └──────────────────────────────────────────┘ │
│ │ │ │ │
│ └───────────┴───────────┘ │
│ │ │
│ ┌──────────────────────────────────────────┐ │
│ │ Dedicated Backend Infrastructure │ │
│ │ • Redis cluster │ │
│ │ • NATS cluster │ │
│ │ • PostgreSQL instance │ │
│ │ • Kafka cluster │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Tenant B (Separate Infrastructure) │
│ [Similar isolated deployment] │
└─────────────────────────────────────────────────────┘
Use Cases:
- Large enterprise applications with high throughput requirements (>10K RPS)
- Regulatory compliance requirements mandating physical infrastructure separation (HIPAA, PCI-DSS, FedRAMP)
- Noisy neighbor elimination for mission-critical applications
- Independent upgrade cycles - tenant controls when to upgrade Prism versions
- Custom performance tuning - dedicated resources can be sized precisely for workload
Characteristics:
- Complete isolation: No shared infrastructure between tenants
- Dedicated resources: CPU, memory, network, storage all tenant-specific
- Independent lifecycle: Each tenant deployment can be upgraded, scaled, or maintained independently
- Maximum performance: No resource contention with other tenants
- Higher cost: Full infrastructure stack per tenant
Configuration Example (single-tenant-config.yaml):
deployment:
model: single_tenant
tenant_id: enterprise-customer-a
proxy:
replicas: 5 # N-way deployment
resources:
cpu: "4"
memory: "8Gi"
# Each tenant gets dedicated proxy cluster
cluster:
mode: dedicated
load_balancer: haproxy # or nginx, envoy
backends:
# All backends are tenant-specific
redis:
endpoint: "redis.tenant-a.svc.cluster.local:6379"
isolation: physical
nats:
endpoint: "nats.tenant-a.svc.cluster.local:4222"
isolation: physical
postgres:
endpoint: "postgres.tenant-a.svc.cluster.local:5432"
database: "tenant_a_db"
isolation: physical
observability:
# Dedicated observability stack
metrics_endpoint: "prometheus.tenant-a.svc:9090"
traces_endpoint: "tempo.tenant-a.svc:4317"
logs_endpoint: "loki.tenant-a.svc:3100"
Deployment Patterns:
-
Kubernetes Namespace per Tenant:
kubectl create namespace tenant-a
helm install prism-proxy prism/proxy \
--namespace tenant-a \
--values tenant-a-values.yaml -
Bare Metal / VM Deployment:
# Each tenant gets dedicated servers
ansible-playbook deploy-prism.yml \
--extra-vars "tenant_id=tenant-a servers=proxy-a-[1:5]" -
Cloud Provider (AWS):
module "prism_tenant_a" {
source = "./modules/prism-single-tenant"
tenant_id = "tenant-a"
vpc_id = aws_vpc.tenant_a.id
proxy_count = 5
instance_type = "c6i.2xlarge"
}
Operational Considerations:
- Cost: Highest per-tenant cost due to dedicated infrastructure
- Maintenance: Requires separate maintenance windows per tenant
- Monitoring: Dedicated observability stack per tenant increases operational overhead
- Networking: Requires careful network segmentation and firewall rules
- Disaster Recovery: Each tenant needs independent backup and recovery procedures
2. Multi-Tenant (Shared Proxy Pool)
Architecture: Control plane manages pool of proxies using prism-bridge, serving multiple tenants.
┌─────────────────────────────────────────────────────────────┐
│ Prism Control Plane (prism-bridge) │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Namespace Registry │ │
│ │ • tenant-a → proxy-pool-1 │ │
│ │ • tenant-b → proxy-pool-1 │ │
│ │ • tenant-c → proxy-pool-2 (premium tier) │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Load Balancer Integration │ │
│ │ • HAProxy config generation │ │
│ │ • DNS-based routing │ │
│ │ • Service mesh integration (Istio/Linkerd) │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌─────────▼─────┐ ┌──────▼──────┐ ┌────▼──────────┐
│ Proxy Pool 1 │ │ Proxy Pool 2│ │ Proxy Pool N │
│ (Standard) │ │ (Premium) │ │ (High-Perf) │
│ │ │ │ │ │
│ ┌────┐ ┌────┐│ │ ┌────┐ │ │ ┌────┐ │
│ │Px-1│ │Px-2││ │ │Px-3│ │ │ │Px-N│ │
│ └────┘ └────┘│ │ └────┘ │ │ └────┘ │
└───────────────┘ └─────────────┘ └───────────────┘
│ │ │
┌───────▼─────────────────▼─────────────────▼──────────┐
│ Shared Backend Infrastructure (with namespacing) │
│ • Redis (multi-db or keyspace prefixes) │
│ • NATS (subject hierarchies: tenant-a.*, tenant-b.*)│
│ • PostgreSQL (row-level security, schemas) │
│ • Kafka (topic prefixes: tenant-a.*, tenant-b.*) │
└──────────────────────────────────────────────────────┘
Use Cases:
- SaaS platforms serving hundreds or thousands of customers
- Internal platform teams providing data access as a service
- Cost optimization when complete isolation is not required
- Rapid tenant onboarding - add new tenants without provisioning infrastructure
- Development/staging environments where isolation requirements are lower
Characteristics:
- Shared proxy infrastructure: Multiple tenants route through same proxy pool
- Logical isolation: Namespacing and access control separate tenant data
- Resource efficiency: Higher utilization through multiplexing
- Centralized management: Single control plane manages all tenants
- Noisy neighbor risk: One tenant's traffic can impact others
Configuration Example (multi-tenant-config.yaml):
deployment:
model: multi_tenant
control_plane: prism-bridge
prism_bridge:
# Control plane for managing proxy pools
listen_addr: "0.0.0.0:8980"
# Namespace-to-pool mapping
namespace_routing:
- namespace: "tenant-a-*"
pool: "standard"
weight: 1
- namespace: "tenant-b-*"
pool: "standard"
weight: 1
- namespace: "premium-*"
pool: "premium"
weight: 1
# Load balancer integration
load_balancer:
type: haproxy
config_path: "/etc/haproxy/haproxy.cfg"
reload_command: "systemctl reload haproxy"
# Service discovery integration
service_discovery:
type: kubernetes
label_selector: "app=prism-proxy"
proxy_pools:
standard:
replicas: 10
resources:
cpu: "2"
memory: "4Gi"
isolation_level: namespace # See isolation section below
premium:
replicas: 5
resources:
cpu: "4"
memory: "8Gi"
isolation_level: session
backends:
# Shared backends with logical isolation
redis:
endpoint: "redis-cluster.svc.cluster.local:6379"
isolation:
type: keyspace_prefix
format: "tenant:{tenant_id}:{key}"
nats:
endpoint: "nats.svc.cluster.local:4222"
isolation:
type: subject_hierarchy
format: "tenant.{tenant_id}.{subject}"
postgres:
endpoint: "postgres.svc.cluster.local:5432"
isolation:
type: row_level_security
enable_rls: true
tenant_column: "tenant_id"
kafka:
endpoint: "kafka.svc.cluster.local:9092"
isolation:
type: topic_prefix
format: "{tenant_id}.{topic}"
observability:
# Shared observability with tenant labels
metrics_endpoint: "prometheus.svc:9090"
traces_endpoint: "tempo.svc:4317"
logs_endpoint: "loki.svc:3100"
tenant_label: "prism_tenant_id"
prism-bridge Architecture:
prism-bridge is the control plane component for multi-tenant deployments:
- Namespace Registry: Maps tenant namespaces to proxy pools
- Load Balancer Integration: Generates HAProxy/nginx configs, updates DNS records
- Health Monitoring: Tracks proxy health and removes unhealthy instances
- Dynamic Routing: Routes tenant requests to appropriate proxy pool
- Orchestrator Integration: Works with Kubernetes, Nomad, or other orchestrators
Example prism-bridge API:
# Register new tenant
curl -X POST http://prism-bridge:8980/api/v1/tenants \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "tenant-c",
"namespace_pattern": "tenant-c-*",
"pool": "standard",
"isolation_level": "namespace"
}'
# Get tenant routing info
curl http://prism-bridge:8980/api/v1/tenants/tenant-c
# List available proxy pools
curl http://prism-bridge:8980/api/v1/pools
# Update load balancer configuration
curl -X POST http://prism-bridge:8980/api/v1/loadbalancer/reload
Orchestrator Integration:
-
Kubernetes (Controller Pattern):
apiVersion: prism.io/v1alpha1
kind: PrismTenant
metadata:
name: tenant-c
spec:
pool: standard
isolation_level: namespace
namespaces:
- tenant-c-production
- tenant-c-stagingprism-bridge watches for
PrismTenantCRDs and updates routing accordingly. -
Nomad (Service Discovery):
job "prism-bridge" {
group "control-plane" {
task "bridge" {
driver = "docker"
config {
image = "prism/bridge:latest"
}
service {
name = "prism-bridge"
port = "api"
tags = ["control-plane"]
}
}
}
} -
Bare Metal (Address Lists):
# prism-bridge maintains address list file
prism-bridge get-addresses --pool standard > /etc/haproxy/backends-standard.lst
Operational Considerations:
- Cost: Significantly lower per-tenant cost (10-100x reduction)
- Noisy Neighbors: Requires careful resource limits and quality of service policies
- Security: Strong authentication and authorization critical (mTLS, namespace-based ACLs)
- Monitoring: Must track per-tenant metrics to identify noisy neighbors
- Scalability: Can scale to thousands of tenants on same infrastructure
3. Hybrid Tenancy (Tiered Service)
Architecture: Combination of single-tenant for premium customers and multi-tenant for standard customers.
┌───────────────────────────────── ─────────────────────┐
│ Prism Control Plane (prism-bridge) │
│ │
│ Tenant Routing Rules: │
│ • enterprise-tier-* → dedicated proxy pools │
│ • standard-tier-* → shared proxy pools │
└───────────────┬──────────────────┬───────────────────┘
│ │
┌───────▼────────┐ ┌─────▼──────────┐
│ Enterprise │ │ Standard │
│ Dedicated │ │ Shared Pool │
│ Proxy Pool │ │ │
└────────────────┘ └────────────────┘
Use Cases:
- Tiered SaaS pricing: Enterprise customers get dedicated resources
- Migration path: Start multi-tenant, upgrade to single-tenant as customers grow
- Compliance boundaries: Some customers require dedicated infrastructure, others don't
- Performance SLAs: Different SLAs for different customer tiers
Configuration Example:
deployment:
model: hybrid
tenant_routing:
rules:
- match:
tier: enterprise
annual_revenue: ">100000"
action:
deployment: single_tenant
pool: dedicated
- match:
tier: premium
action:
deployment: multi_tenant
pool: premium
isolation_level: session
- match:
tier: standard
action:
deployment: multi_tenant
pool: standard
isolation_level: namespace
Isolation Levels
Isolation levels control how tenant workloads are separated within a shared proxy deployment. These can be configured independently of the tenancy model.