SecurityAug 11, 2026 · 8 min read

MCP server for PostgreSQL: build an authorization-aware cache

Caching makes an MCP server for PostgreSQL faster. A poorly keyed cache can also erase the authorization boundary.

Two users may ask the same question while having different tenants, roles, approved views, row-level policies, or environments. If the server keys only on tool name and arguments, one user's discovery metadata or result can be served inside another user's context.

The cache key is therefore part of the security model.

Identify what is being cached

Do not apply one policy to every cached object. A PostgreSQL MCP server may cache:

  • tool catalogs and descriptions;
  • schema and column metadata;
  • authorization or policy decisions;
  • connection and capability checks;
  • query plans or prepared operation shapes;
  • database results;
  • pagination or resumable-state handles.

Each class has a different confidentiality level, staleness risk, and invalidation trigger.

Build the authorization fingerprint

A safe key should include every attribute that can change what the caller is allowed to discover or receive. Depending on the architecture, that can include:

  • authenticated principal or service identity;
  • tenant and organization;
  • role and database execution identity;
  • environment, region, and database target;
  • policy and entitlement version;
  • approved tool-catalog version;
  • schema or migration version;
  • normalized arguments and source watermark.

Hash the canonical fingerprint for storage, but retain enough structured audit data to explain why a hit was allowed. Do not place raw tokens or secrets in cache keys or logs.

Tool discovery is authorization-sensitive

A tool catalog can reveal table names, business concepts, integrations, and operations even before a query executes. Generate discovery output from the caller's authorized surface, and key it by the relevant identity, tenant, policy, environment, and catalog version.

For larger catalogs, use scoped or progressive discovery rather than publishing every possible database action to every client. Related: MCP tool discovery for large database schemas.

Policy caches need short, explicit lives

An authorization result should expire or invalidate when group membership, tenant assignment, role, policy, approval, session, or credential state changes. A long TTL turns a revoked permission into continued access.

Bind policy entries to the authenticated subject and policy version. On sensitive operations, prefer a fresh policy evaluation or a narrowly bounded decision token with audience, purpose, expiry, and revocation semantics.

Result caches need source and scope

A result key based on SQL text or normalized tool arguments is incomplete. Include tenant, principal or approved sharing group, database identity, environment, policy version, schema version, and source freshness watermark.

The cached payload should preserve the same limits and evidence as a live result: filters, row and byte counts, truncation, redaction, source time, and trace lineage. A cache hit must not make the response less auditable.

Concrete example: tenant-scoped inventory

Two MSP operators call inventory_summary with {"status":"unsupported"}. Their JSON arguments are identical. Their tenant, approved customer set, database role, and row-level policy are not.

A weak cache returns the first operator's summary to the second. A safer key combines the operation version, normalized arguments, tenant and customer scope, execution role, policy version, schema version, and source watermark.

If customer scope changes, the old entry becomes unreachable immediately—even if its time-based TTL has not elapsed.

Prevent cache stampedes without sharing authority

Request coalescing and single-flight locks must use the same authorization-aware key as the cached object. Otherwise concurrent requests can share work across boundaries before the result is even stored.

Use bounded leases with ownership tokens, propagate cancellation, and record whether a response was computed, coalesced, or served from cache. Capacity pressure should cause eviction or load shedding, not fallback to a broader key.

Test negative reuse

  1. Repeat identical arguments across two tenants.
  2. Change role or group membership while an entry remains warm.
  3. Revoke an approval and replay the request.
  4. Deploy a schema change without changing the prompt.
  5. Switch production and staging targets.
  6. Rotate credentials and terminate a session.
  7. Trigger concurrent misses from principals with different scopes.
  8. Verify that cache logs contain no secrets or raw sensitive results.

Test for the absence of cross-scope hits. A high aggregate hit rate can hide a serious isolation defect.

Where Conexor fits

Conexor provides MCP infrastructure for connecting AI clients to databases and APIs through governed tools. Authorization-aware discovery, execution, and evidence keep performance optimizations inside the intended boundary.

Explore the MCP server for PostgreSQL

Continue with the Postgres MCP production checklist and PostgreSQL row-level security for MCP.

Relay

Quick questions

Relay

Quick questions

Ask me