A shared cache can return another customer’s data when the tenant identifier is missing from a key or an HTTP response varies by a tenant header the cache ignores. Treat cache scope as part of the authorization boundary.
Last updated: September 26, 2026.
function projectCacheKey(int $tenantId, int $projectId, int $version): string
{
return "tenant:{$tenantId}:project:{$projectId}:v{$version}";
}
$key = projectCacheKey($sessionTenantId, $projectId, $projectVersion);
$project = $cache->get($key);
if ($project === null) {
$project = $repository->findForTenant($sessionTenantId, $projectId);
$cache->set($key, $project, 300);
}The tenant ID is derived from verified server-side context, and the database lookup remains tenant-scoped. A version component makes invalidation explicit after changes.
Define every cache dimension
Include tenant, resource, locale, permission-sensitive representation, and relevant version in the key. User-specific results also need a user or role dimension. Do not trust an unverified request header merely because it is convenient for a reverse proxy.
Microsoft’s multitenant API guidance explicitly warns that tenant-varying data needs the tenant identifier in its cache key.
Invalidate without cross-tenant scans
Use predictable tenant prefixes and version tokens. On update, delete the exact resource key or increment a tenant-scoped generation. Avoid global flushes, and avoid wildcard deletion on the request path. When offboarding, a controlled background job can scan only the tenant prefix.
Protect availability and privacy
- Set per-tenant size or item limits where possible.
- Avoid caching secrets or highly sensitive data unless the cache is designed for it.
- Encrypt transport and restrict cache credentials and networks.
- Log misses and latency by tenant without logging cached payloads.
- Test two tenants with identical resource IDs and different values.
Per-tenant quotas help prevent a noisy neighbor. The underlying repository must still apply tenant-isolated queries because cache misses reach the database.