audit-org-isolation
Find Express route handlers that touch multi-tenant Prisma models without going through injectOrgFilter / injectWriteFilter. Use after adding new routes, before committing, and during security review.
Files1
View on GitHubSKILL.md.claude/skills/audit-org-isolation/SKILL.md
GitHubaudit-org-isolation
Multi-tenant data isolation is the project's #1 security invariant. This skill greps for any handler that bypasses it.
Background
The middleware injectOrgFilter (reads) and injectWriteFilter (writes) live at apps/api/middleware/org-isolation.ts. They append organizationId = req.user.organizationId to Prisma queries automatically. Any handler that talks to a multi-tenant model without these middlewares is a leak risk.
Steps
- List multi-tenant models by grepping
data/schema/prisma/schema.prismafororganizationId. - For each model, grep
apps/api/routes/for direct usage:prisma.<modelName>.find prisma.<modelName>.update prisma.<modelName>.delete prisma.<modelName>.create - For each match, check the surrounding handler:
- Is the route mounted with
authenticateToken+ the org-isolation middleware? - OR does the handler explicitly include
organizationId: req.user.organizationIdinwhere?
- Is the route mounted with
- Flag violations — handlers that touch a multi-tenant model with neither protection.
- Report as a table:
File:line Model Operation Risk - Do not fix automatically — show the user the violations first. They may have intentional admin-only routes.
Verification
- All multi-tenant models scanned
- Report grouped by file
- Each violation includes file:line for easy navigation
Notes
WEBSITE_ADMINroutes are allowed to bypass — flag them but mark as[admin]- The
usersandorganizationstables themselves have special rules — check existing patterns before flagging - See [[Architecture/Org Isolation]] in the vault for full context