LEAP
LEAP builds skills through two pipelines: Branch A distills a skill from raw data, while Branch B combines multiple skills into…
Security-first SOP for multi-tenant RAG systems. Activate when a calling agent is building, reviewing, or debugging any retrieval pipeline whose vector store is shared across more than one user, organisation, workspace, customer, or permission scope. Encodes the single
Claude Code
$ npx -y skills add agentsope/SkillAlchemy --skill agentsop-multi-tenant-rag --agent claude-code
Codex
$ npx skills add agentsope/SkillAlchemy --skill agentsop-multi-tenant-rag -a codex -y
Cursor
$ npx skills add agentsope/SkillAlchemy --skill agentsop-multi-tenant-rag -a cursor -y
Gemini CLI
$ npx skills add agentsope/SkillAlchemy --skill agentsop-multi-tenant-rag -a gemini-cli -y
GitHub Copilot
$ npx skills add agentsope/SkillAlchemy --skill agentsop-multi-tenant-rag -a github-copilot -y
OpenCode
$ npx skills add agentsope/SkillAlchemy --skill agentsop-multi-tenant-rag -a opencode -y
Windsurf
$ npx skills add agentsope/SkillAlchemy --skill agentsop-multi-tenant-rag -a windsurf -y
name: agentsop-multi-tenant-rag version: 0.1.0 description: | Security-first SOP for multi-tenant RAG systems. Activate when a calling agent is building, reviewing, or debugging any retrieval pipeline whose vector store is shared across more than one user, organisation, workspace, customer, or permission scope. Encodes the single non-negotiable rule — **filter at the vector store query, never after retrieval / never after rerank** — together with the per-vendor query-time filter APIs (Pinecone namespaces + `$eq`/`$in`, Weaviate `multiTenancyConfig` + tenant handle, Qdrant `is_tenant` payload index + `Filter.must`, Chroma `where`, pgvector RLS), and the cross-framework adapters (LlamaIndex `MetadataFilters`, LangChain `filter=` dict). Frame the work as preventing CVE-2024-41892 / EchoLeak / Slack-AI-class cross-tenant leakage, not as "adding a filter for relevance". trigger_keywords: - "multi-tenant RAG" - "tenant isolation" - "metadata filter" - "namespace per tenant" - "multitenancy vector store" - "RLS pgvector" - "cross-tenant leak" - "RAG security" - "workspace separation" when_to_use: - "any RAG / retrieval pipeline whose corpus is shared across >1 tenant, customer, org, user, or permission scope" - "reviewing PRs that touch `vector_store.query` / `index.as_retriever` / `similarity_search` / `vectorstore.query_points`" - "designing ingestion for a SaaS knowledge base, internal corpus split by team, or per-customer corpus" - "responding to a 'we got the wrong document' bug — confirm it isn't actually a cross-tenant leak first" - "before shipping any RAG endpoint that exposes retrieved content to end users" when_not_to_use: - "single-tenant / single-user corpora with no access scopes — over-engineering" - "purely internal eval / offline notebooks against fully public data" - "the retrieval boundary is enforced by a per-tenant collection / index that the application can never address by name — already isolated"
> Third-person operating model for a coder agent that owns retrieval correctness > across tenant boundaries. The audience is the LLM agent writing or reviewing > the code — not the end user.
> **One sentence**: *Isolation lives at the vector store query boundary, not > at the model. Anything that reaches the LLM's context window has already > leaked.*
---
Activate this skill whenever **any** of the following holds:
1. The codebase contains a retrieval call (`vector_store.query`, `query_points`, `similarity_search`, `as_retriever().retrieve(...)`, raw `pgvector` `ORDER BY embedding <-> $1`) **and** the corpus serves more than one tenant, customer, organisation, workspace, user, or permission scope. 2. The user mentions any of: multi-tenant RAG, namespace, tenant, workspace, `tenant_id`, `org_id`, `user_id`, "cross-customer", "shared index", "knowledge base per team". 3. A bug report says "User A saw User B's document", "wrong company's data surfaced", "the assistant cited a doc I don't have access to", or anything that smells like cross-context bleed. 4. PR review: any new code calling a vector store **without** a tenant-scoped filter argument, or filtering only on the returned `nodes` / `documents` list after retrieval. 5. A new RAG endpoint is about to ship and tenant scoping has not been explicitly audited.
Do **not** activate when:
Q&A).
collection per tenant via infrastructure the application code cannot override (e.g. one Pinecone index per customer with credentials issued per-tenant). In that case the isolation lives in IAM, not in this skill.
---
Three principles. If a design violates any of them the system is exploitable, regardless of how good the LLM prompt is.
The boundary is the vector store query call. **Whatever crosses that boundary is in the trust set.** An LLM, a reranker, or a postprocessor that "filters out" foreign-tenant chunks is operating *inside* the breach: those tokens have already been embedded, retrieved, scored, and exposed to attacker-controlled prompts. CVE-2024-41892 (Pinecone, 2024) is the canonical demonstration — RBAC checks executed *after* retrieval allowed sentinel data to cross namespace boundaries before the access check fired. (See *we45*, *CSO Online* references.)
> **Operational corollary**: any code shaped `results = vs.query(...); results > = [r for r in results if r.metadata["tenant"] == ctx.tenant]` is a security > defect, not a style nit. The leak already happened — you only hid it from > the user.
A query-time filter is only enforceable if every vector carries the key. The two failure shapes:
shared global record returned to all tenants — it matches no filter predicate that requires equality.
rather than from the request's authenticated session — attacker can craft document content that re-labels itself.
The tenant key **must** come from the authenticated session at ingestion time and be written into the immutable payload / metadata column. Treat it like a foreign key to your tenants table.
Most production-grade stacks layer two mechanisms:
| Layer | Mechanism | What it stops | |---|---|---| | Storage | Per-tenant namespace / shard / collection / RLS policy | Operator bugs, mis-routed queries, ops mistakes | | Query | `filter={tenant_id: $session.tenant}` on eve
Turn people, methods, and experience into installable, reusable agent skills. SkillAlchemy is an open-world agent skill creation system that turns underspecified skill briefs and open-world sources into installable, reusable agent skills.
LEAP builds skills through two pipelines: Branch A distills a skill from raw data, while Branch B combines multiple skills into…
Lens — Add a cognitive lens to any problem. It accepts a task description and produces an enhanced description that surfaces…
Cross-framework enhancement overlay for choosing a multi-agent topology BEFORE writing any agent. A binary-question rubric — is…
SOP for terminal-based, git-native AI pair programming with Aider (git work-tree + tree-sitter repo-map + edit-format +…
Screens biomedical / life-science papers for signs of data fabrication, image manipulation, and statistical anomalies, using the…
Universal discipline for any LM-driven loop — agent retries, plan-act-observe, multi-agent handoffs, optimiser passes, test-fix…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.