Skip to content

fix: partition server-side caches by customerId to prevent leakage - #65

Open
dylan-klein wants to merge 2 commits into
mainfrom
fix/cache-partitioning
Open

fix: partition server-side caches by customerId to prevent leakage#65
dylan-klein wants to merge 2 commits into
mainfrom
fix/cache-partitioning

Conversation

@dylan-klein

@dylan-klein dylan-klein commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

MOTIVATION

In service_account mode, multiple administrators from different tenants share the same global Service Account credentials and thus generate the same OAuth access token. Because server-side caches (MCP tools, prompts, users, and risky activity) previously keyed their data using only the token hash, this caused cross-tenant cache collisions. For example, Admin B (Tenant B) could query the same endpoint and receive cached directory data or activity logs belonging to Admin A (Tenant A), representing a critical data leakage vulnerability.

MAIN CHANGES

  • Cache Key Isolation: Modified buildCallerCacheKey in src/lib/cache-key.ts to accept an optional customerId parameter and append |c:<customerId> to the resulting cache key string.
  • Route Integration: Refactored API routes (/api/users, /api/tools, /api/prompts, /api/insights/risky-activity) and internal fetch helpers (activity-data.ts, mcp-tools.ts) to retrieve the active customerId from the session and pass it to the cache key builder.
  • Review Fixes: Added input format validation to ensure only alphanumeric Customer IDs starting with 'C' are accepted. Moved cookie resolution inside route try blocks to prevent unhandled 500 crashes on corrupted cookies.
  • Test Suite updates: Updated cache-key.test.ts and next/headers mocks in integration tests to support the session validation flow.

DESIGN DECISIONS

  • Rather than creating separate backend caches per auth mode, we unified the cache key structure to dynamically append the tenant ID when running under Service Account mode. This keeps the caching logic clean and unified across both user OAuth and service account deployment models.

TAG=agy
CONV=b3471264-2592-4924-b031-267b4bf62326

- Export and reuse CUSTOMER_ID_REGEX in constants.ts and env.ts.
- Validate customerId format in sa-config POST API route and add a test case.
- Move getActiveCustomerId and callerKey inside try/catch blocks in API routes to prevent uncaught 500 crashes.

TAG=agy
CONV=b3471264-2592-4924-b031-267b4bf62326
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant