Data-Level Isolation
Beyond database schemas, namespace boundaries, and network policies, the MATIH Platform enforces tenant isolation at the data level in caches, event streams, object storage, and search indexes. This page documents how tenant isolation is maintained across all data stores.
Cache Isolation (Redis)
Redis keys are namespaced by tenant to prevent cross-tenant cache pollution:
| Key Pattern | Example |
|---|---|
{tenant_id}:{service}:{key} | acme-corp:ai-service:session:abc-123 |
{tenant_id}:{service}:{entity}:{id} | acme-corp:query-engine:result:q-456 |
The TenantAwareCacheManager automatically prefixes all keys:
public class TenantAwareCacheManager {
private String buildKey(String key) {
String tenantId = TenantContext.getCurrentTenantIdOrDefault("system");
return tenantId + ":" + key;
}
}Event Isolation (Kafka)
Kafka events carry tenant context in two places:
| Location | Purpose |
|---|---|
| Message key | tenant_id ensures partition affinity and ordering |
| Event payload | tenantId field for consumer filtering |
This double encoding ensures that even if a consumer processes events from a shared topic, it can filter by tenant.
Object Storage Isolation (MinIO)
Objects are isolated by tenant-prefixed paths:
| Pattern | Example |
|---|---|
{bucket}/{tenant_id}/{path} | mlflow-artifacts/acme-corp/experiment-1/model.pkl |
Bucket policies restrict access to the tenant's prefix.
Search Index Isolation (Elasticsearch)
Elasticsearch documents include a tenant_id field, and all queries include a tenant filter:
{
"query": {
"bool": {
"must": [
{"match": {"action": "QUERY_EXECUTED"}},
{"term": {"tenant_id": "acme-corp"}}
]
}
}
}Vector Store Isolation (Qdrant)
Vector search results are filtered by tenant ID in the metadata payload:
{
"vector": [0.1, 0.2, ...],
"filter": {
"must": [
{"key": "tenant_id", "match": {"value": "acme-corp"}}
]
},
"limit": 5
}Graph Store Isolation
Graph database queries include tenant filters:
MATCH (t:Table)-[:HAS_COLUMN]->(c:Column)
WHERE t.tenant_id = 'acme-corp'
RETURN t.name, c.nameSession Isolation
User sessions are scoped by tenant in Redis:
| Key | TTL |
|---|---|
{tenant_id}:session:{session_id} | 8 hours |
Session data can only be accessed with the matching tenant context.
Isolation Verification
| Store | Verification Method |
|---|---|
| PostgreSQL | Integration tests creating data as Tenant A, querying as Tenant B (expect empty) |
| Redis | Key prefix collision test |
| Kafka | Consumer group isolation test |
| Elasticsearch | Cross-tenant query test |
| MinIO | Bucket policy enforcement test |
Related Pages
- Database Isolation -- Schema-level PostgreSQL isolation
- Network Isolation -- Network-level isolation
- Tenant Context -- Application-level context propagation