Skip to main content

SaaS tenant-aware caching: prevent cross-customer data leaks

Secure shared SaaS caches with tenant-scoped keys, authorization before cache reads, safe invalidation and cross-tenant tests.

In this guide

How can a SaaS team prevent tenant data leaking through a cache?

A shared application cache is safe only when the cached value and its key preserve the access boundary of the request that created it. Include the authorized tenant and every representation-changing input in the key, authorize before returning a hit, and test cache reads across different customers. This guide covers application and distributed caches such as Redis; edge CDN caching has a separate set of routing and response rules.

Map every cache that can contain customer-specific data

Inventory in-process memoization, framework query and fragment caches, object caches, report results, session stores and distributed Redis entries. Record whether each value is public, user-specific, tenant-specific or sensitive, who may populate it, how long it lives and how a permission or data change invalidates it. A database row policy does not automatically protect an already-cached copy.

Build keys from server-verified tenant and identity context

Use a stable tenant identifier resolved after authentication and authorization, then add the resource, permission scope, locale, query parameters or other inputs that change the returned representation. Do not use an untrusted tenant parameter alone. Avoid putting raw email addresses, access tokens or personal data in cache keys that may appear in diagnostics.

Authorize before serving a cache hit

A cache key is not a substitute for a product permission check. Confirm the caller still belongs to the tenant and may perform the requested action before returning a private hit; membership or role changes can occur while an entry is alive. For sensitive values, prefer a short lifetime or no shared cache if the invalidation path cannot be trusted.

Tenant cache boundary worksheet
Cache and data sensitivityAuthorized key dimensionsRead and write permissionsInvalidation triggerCross-tenant test and owner
User profile or settings
Tenant dashboard or report
Shared public reference data

How should teams scope Redis and other shared caches?

Treat a tenant key prefix as namespacing, not proof of isolation

A prefix such as tenant ID plus resource type makes ownership easier to inspect and invalidate, but application code that can issue arbitrary Redis commands may still access other prefixes. Redis ACLs can limit commands and key patterns for named users, yet commands that operate on the whole database are governed separately. Evaluate the exact Redis version and managed-service behavior before relying on ACLs as a boundary.

Give each service a narrow cache identity

Separate cache credentials by application or worker where the service supports it, allow only the commands and key patterns needed, keep Redis private to trusted application networks and use authenticated encrypted connections where available. A shared default account with broad command access turns a bug in one consumer into a larger cache blast radius.

Keep shared values separate from private tenant results

A public product catalogue or feature definition can use a shared key only when its value is genuinely the same for every eligible caller. For tenant-specific configuration, billing, permissions or records, include the authorized tenant and applicable user scope. Review fallback behavior so a missing tenant-specific key cannot return a generic or previous tenant's value.

How do you test cache invalidation and tenant separation?

Use two tenants and vary identity, permissions and request shape

Request the same resource as users from tenant A and tenant B, as two roles within one tenant, and after one user's membership is removed. Repeat with different locales, filters, pagination, feature flags and authorization outcomes. Assert that both cache misses and hits return only the authorized representation.

Invalidate after data, role and tenant lifecycle changes

Define invalidation for updates, deletes, role changes, membership removal, tenant suspension and account offboarding. Test retries and simultaneous refreshes so an older response cannot repopulate a key after a newer value or revocation. If event-driven invalidation is delayed, use a safe expiry and check authorization again on read.

Protect observability and avoid cache stampedes

Log key templates, hit or miss outcomes, tenant pseudonyms and latency without logging raw cached records or credentials. Alert on unexpected key growth, broad command usage and error spikes. Use bounded refresh, jitter or request coalescing where appropriate so expiration does not trigger a costly burst that pressures one tenant or the whole service.

Sources for this point: Redis securityOWASP Cheat Sheet: Logging

SaaS cache security FAQs

Is adding the tenant ID to a Redis key enough?

No. It reduces accidental key collisions, but every write and read path must use the same server-verified tenant scope. Redis ACLs, network restrictions, application authorization and tests provide additional controls; a broad credential or global command can bypass a naming convention.

Should a SaaS application cache private customer data?

It can when access checks, key design, expiry, invalidation, storage permissions and operational logs are designed and tested for that data. Avoid caching highly sensitive or rapidly changing values if the team cannot reliably revoke or isolate them.

Does CDN security cover application caches?

No. A CDN handles edge requests and response caching, while Redis or an application cache may sit behind authentication and store different objects. Review each layer's key, access decision, lifetime and invalidation behavior separately.

Sources for this point: Understand Cache PoliciesRedis security