Skip to content
gentic.news — AI News Intelligence Platform
Connecting to the Living Graph…

Listen to today's AI briefing

Daily podcast — 5 min, AI-narrated summary of top stories

Two developers reviewing a PostgreSQL server dashboard with a highlighted cache key field, while a red warning icon…

Your MCP Cache Key Is an Authorization Hole: 6 Cache Classes to Fix It

MCP cache keys must include auth attributes like tenant and role. Separate six cache classes to prevent cross-scope leaks. Test with negative cross-tenant scenarios.

·20h ago·4 min read··27 views·AI-Generated·Report error
Share:
Source: dev.tovia devto_mcp, gn_mcp_protocol, hn_claude_codeMulti-Source
How do I make my MCP server cache authorization-aware to prevent cross-tenant data leaks?

Include principal, tenant, role, environment, policy version, schema version, normalized args, and source watermark in every MCP cache key. Separate cache classes for discovery, schema, policies, operations, results, and state. Never key on tool name and JSON args alone.

TL;DR

Cache keys with only tool name and args leak data across tenants in PostgreSQL MCP servers. Separate six cache classes and include auth attributes.

Caching makes your PostgreSQL MCP server fast. But if your cache key is just tool name + JSON arguments, you've quietly deleted your authorization boundary.

Two users can call the same tool with identical arguments while belonging to different tenants, roles, or environments. With a weak key, the second user gets the first user's cached results — including rows they were never allowed to see.

This isn't hypothetical. It's the default behavior of many naive MCP server implementations.

Key Takeaways

  • MCP cache keys must include auth attributes like tenant and role.
  • Separate six cache classes to prevent cross-scope leaks.
  • Test with negative cross-tenant scenarios.

The Problem: Cache Keys That Ignore Identity

Most MCP servers cache by hashing the tool name and the serialized arguments. That works for a single-user local setup. But as soon as you deploy a PostgreSQL MCP server behind a gateway serving multiple tenants, that key is insufficient.

Consider two users: Alice in tenant A and Bob in tenant B. Both call query_database with {"sql": "SELECT * FROM orders"}. A naive cache stores the result under query_database:{"sql":"..."}. Bob's identical call hits the cache and receives Alice's orders.

Even worse: tool discovery metadata can reveal sensitive structure. The list of available tools, their schemas, and their descriptions may differ per role. Caching that metadata without the caller's role leaks internal API shapes.

The Fix: Separate Cache Classes and Enrich the Key

The source article recommends two moves: separate cache classes, then include every authorization-relevant attribute in the key.

1. Separate Six Cache Classes

Don't use one cache for everything. Split into:

  • Tool discovery — the list of tools and their schemas
  • Schema metadata — table/column definitions
  • Policy decisions — whether a caller may perform an operation
  • Prepared operation shapes — compiled SQL or query plans
  • Database results — actual rows returned
  • Resumable state handles — pagination or streaming state

Each class has different sensitivity and different invalidation requirements. Policy decisions change when roles change; database results change when data changes. Mixing them forces you to invalidate everything on any change.

2. Build an Authorization-Aware Key

For every cache entry, compute the key from:

  • Principal (user ID)
  • Tenant ID
  • Execution role
  • Environment (prod/staging/dev)
  • Policy version
  • Tool-catalog version
  • Schema version
  • Normalized arguments (canonical JSON, sorted keys)
  • Source watermark (data lineage or timestamp)

Include all of these in the hash. If any one changes, the cache miss is correct.

Three Details That Matter in Practice

MCP Authorization Scope Is the Hole the New Spec Handed You

Tool discovery leaks structure

Even listing available tools can reveal sensitive internal schema. Cache discovery responses per role and tenant, not globally.

Single-flight coalescing must use the same key

If you coalesce concurrent identical requests (single-flight), the coalescing key must be the same authorization-aware key. Otherwise, two users' requests merge into one execution, and the second user receives the first user's authorized result.

Cache hits must preserve evidence

A cache hit must still apply freshness, truncation, redaction, and trace metadata. Don't return a cached result that skips row-level security or truncation rules applied on the original query.

The Negative Test

Warm the cache, then repeat identical arguments across:

  • Another tenant
  • Another role
  • Another environment
  • A revoked approval
  • A changed schema

Measure the absence of cross-scope hits — not just the aggregate hit rate. A high hit rate with cross-tenant leaks is a security incident, not a performance win.

Try It Now

If you're building or maintaining a PostgreSQL MCP server, audit your cache key today:

  1. Find every cache.put and cache.get call.
  2. Check the key composition. Does it include tenant and role?
  3. Separate cache classes if you haven't.
  4. Add a negative test that simulates cross-tenant identical calls.

This applies whether you use Redis, in-memory maps, or PostgreSQL itself as your cache layer. The principle is the same: the cache key is part of your authorization model.

The full guide with implementation details is available at the source article.


Source: dev.to

Source: gentic.news · · author= · citation.json

AI-assisted reporting. Generated by gentic.news from multiple verified sources, fact-checked against the Living Graph of 4,300+ entities. Edited by Ala SMITH.

Following this story?

Get a weekly digest with AI predictions, trends, and analysis — free.

AI Analysis

Claude Code users building MCP servers should treat cache keys as security boundaries, not performance optimizations. The immediate action: audit any PostgreSQL MCP server you maintain. Add tenant and role to every cache key, and separate the six cache classes. Use Claude Code to generate the audit script — ask it to grep for cache.put/get calls and flag keys missing auth attributes. Second, update your testing workflow. Add negative tests that simulate cross-tenant identical calls. Claude Code can help write these tests: prompt it to generate a test suite that warms the cache with one tenant's credentials and verifies another tenant gets a cache miss. This is the kind of task Claude Code excels at — repetitive, pattern-based code generation across multiple files. Finally, when using third-party MCP servers, verify their caching behavior. A server that caches results without authorization awareness is a liability. Before wiring it into your Claude Code workflow, check its source or documentation for cache key composition. If it's opaque, run the negative test yourself.
This story is part of
The Protocol Schism: Anthropic's MCP Stack vs. OpenAI's Agent Lock-In
How a developer convention is splitting AI into two incompatible ecosystems, with Meta and Google caught in the middle
Compare side-by-side
Model Context Protocol vs PostgreSQL

Mentioned in this article

Enjoyed this article?
Share:

AI Toolslive

Five one-click lenses on this article. Cached for 24h.

Pick a tool above to generate an instant lens on this article.

Related Articles

From the lab

The framework underneath this story

Every article on this site sits on top of one engine and one framework — both built by the lab.

More in Opinion & Analysis

View all