How incomplete cache identity lets one user or tenant receive another user’s cached data.
Cache key scope is one of the most important security boundaries in a caching system. If the key does not include every dimension that changes the correct answer, one request can reuse another request’s cached result incorrectly. When that missing dimension is user, tenant, locale, authorization scope, or policy context, the result is not just stale data. It is data leakage.
Teams often treat key design as a performance detail. It is not. The key defines identity. If identity is incomplete, the cache may confidently serve the wrong user’s or wrong tenant’s data with perfect speed.
flowchart LR
A["Request: /account"] --> B["Key built only from path"]
B --> C["cache key = page:/account"]
C --> D["Shared cache returns response for previous user"]
D --> E["Confidential data leaked"]
The most dangerous cache bugs are often not about expiration. They are about scope. A cache that serves old public data is annoying. A cache that serves another user’s private data is a security incident.
Scope mistakes usually happen when:
Vary-style semanticsNot every request attribute belongs in the key, but every attribute that changes the meaning or visibility of the answer must be reflected somehow.
That may include:
1safe_key_dimensions:
2 account_overview:
3 - user_id
4 - tenant_id
5 - locale
6 public_product_page:
7 - product_id
8 - locale
9 - currency
This example contrasts an unsafe shared key with a safer scoped one.
1function unsafeKey(path: string) {
2 return `page:${path}`;
3}
4
5function saferAccountKey(path: string, tenantId: string, userId: string, locale: string) {
6 return `page:${path}:tenant:${tenantId}:user:${userId}:locale:${locale}`;
7}
What to notice:
How do you decide whether a request attribute should be part of cache identity or not?
The stronger answer is that an attribute belongs in identity whenever changing it can change the content, visibility, or policy of the response. If leaving the attribute out could let one actor see data intended for another, it is part of the security boundary and must be modeled explicitly.