Tenant-safe caches, search and files
Extends tenant isolation beyond database rows to caches, search suggestions, derived indexes and stored file access.
tenant-aware-cache-search-files
Team members using this skill
When is it useful?
Use it when apparently scoped APIs still share cache entries, autocomplete values or object URLs across workspaces.
What does it help you do?
- Namespaces cache keys with verified tenant identity.
- Filters search results, suggestions and facets on the server.
- Partitions storage keys and authorizes signed URL issuance.
Try asking this
Test identical search terms and filenames in two workspaces without cross-tenant results. Warm search and file caches in workspace A, then repeat in B. Counts, suggestions and signed downloads must contain only B's authorized data.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Tenant-Aware Cache, Search & Files
When to Use
Use when integrating or reviewing caching layers (Redis, Memcached, in-memory LRU, HTTP/CDN), search engines (PostgreSQL FTS, Elasticsearch/OpenSearch, Meilisearch, Typesense, Algolia), or file/blob storage in a multi-tenant application.
1. Cache Isolation (Redis, In-Memory & HTTP/CDN)
Unprefixed cache keys (project:123, dashboard:stats, settings) are one of the most frequent sources of cross-tenant data leaks:
- Mandatory Key Namespacing: Wrap the cache client so every tenant-scoped operation automatically prepends the verified
tenantId:const cacheKey = `tenant:${ctx.tenantId}:${namespace}:${resourceId}`; - Fail-Closed Wrapper: If
ctx.tenantIdis missing or empty, the cache wrapper must throw an error rather than generatingtenant:undefined:dashboard:stats(which would become a shared cache key across all unauthenticated/broken calls!). - HTTP & CDN Cache Headers:
- For workspace-authenticated API responses and SSR pages, set
Cache-Control: private, no-store(or includeVary: Authorization, Cookie, X-Workspace-Idwhere private browser caching is intended) so shared CDN or reverse-proxy caches never serveTenant A's response toTenant B.
- For workspace-authenticated API responses and SSR pages, set
2. Full-Text & Search Index Isolation
Search engines often live outside the primary relational database and do not enforce SQL foreign keys:
- Index Every Document with
tenant_id: Every indexed document must carry a non-nullable, filterabletenant_id(workspace_id) facet/attribute. - Server-Enforced Search Filter:
- Never accept raw filter expressions directly from the client.
- Inject
filter: "tenant_id = '<verified_tenant_id>'"on the server (or issue short-lived, cryptographically signed Scoped Search API Keys in Meilisearch/Typesense/Algolia that embed an immutabletenant_idfilter).
- Autocomplete, Facets & Spellcheck / Suggestions:
- Ensure facet counts, "did you mean" suggestions, and popular-query completions are Partitioned by
tenant_id—global autocomplete dictionaries can leak another customer's confidential project or client names!
- Ensure facet counts, "did you mean" suggestions, and popular-query completions are Partitioned by
- Synchronous / Outbox Deletion on Workspace or Record Removal:
- When a record or entire workspace is deleted, remove its documents from the search index via a transactional outbox so deleted or cross-tenant items never linger in search results.
3. File & Object Storage Tenant Boundaries
- Tenant-Partitioned Storage Keys: Prefix object storage keys with the immutable workspace ID (
tenants/${tenantId}/files/${uuidv7}) so storage lifecycle rules, per-tenant byte accounting, and tenant deletion sweeps are cleanly isolated. - Authorization Before Presigned URL Issuance:
- Never allow a user in
Tenant Ato request a download or upload URL for afileIdwithout first queryingSELECT 1 FROM files WHERE id = $1 AND tenant_id = $2using the verifiedtenantId. - Do not deduplicate uploaded files across different tenants if doing so exposes whether another tenant already uploaded a given confidential document (cross-tenant hash oracle) or complicates single-tenant erasure.
- Never allow a user in
Included files 1
SKILL.md
