
Convex Security Audit
Audit a Convex backend for authorization bugs, leaky queries, unsafe actions, and missing rate limits before production ship.
Overview
convex-security-audit is an agent skill most often used in Ship (also Build, Operate) that deep-reviews Convex authorization, data access boundaries, action isolation, and rate limiting.
Install
npx skills add https://github.com/waynesutton/convexskills --skill convex-security-auditWhat is this skill?
- Deep review patterns for authorization logic and role checks in Convex functions
- Data access boundary checks between queries, mutations, and public clients
- Action isolation and side-effect safety for Convex actions
- Rate limiting and abuse-prevention review patterns
- Four review themes: authorization logic, data access boundaries, action isolation, rate limiting
Adoption & trust: 1.3k installs on skills.sh; 402 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Convex app is feature-complete but you are unsure whether queries, mutations, and actions actually enforce auth and tenant boundaries under abuse.
Who is it for?
Indie SaaS builders on Convex preparing for launch or a major permissions refactor.
Skip if: Non-Convex stacks, greenfield ideas with no backend, or compliance certifications that require a formal third-party audit only.
When should I use this skill?
Before shipping a Convex app, after major auth changes, or when the user asks for a Convex security or authorization audit.
What do I get? / Deliverables
You receive a security-oriented audit checklist outcome with prioritized fixes for Convex-specific access and isolation patterns before users hit production data.
- Security findings grouped by authorization, data access, actions, and rate limiting
- Prioritized remediation guidance for Convex-specific patterns
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Security audit is a pre-ship and pre-launch gate for backends already built on Convex. The skill name and patterns target authorization, data boundaries, and action isolation—classic app security review, not infra monitoring.
Where it fits
Run the audit on your Convex `convex/` folder the week before enabling paid plans and public sign-up.
After adding team roles, audit whether new mutations still respect document ownership boundaries.
Re-audit action handlers after a report of users triggering cross-tenant reads.
How it compares
Convex-focused authorization audit skill, not a generic npm vulnerability scanner or infrastructure CSPM tool.
Common Questions / FAQ
Who is convex-security-audit for?
Solo and small-team builders shipping Convex-backed apps who want agent-guided review of auth, data access, actions, and rate limits.
When should I use convex-security-audit?
In Ship before launch; in Build when adding new roles or public APIs; in Operate after auth incidents or before scaling traffic.
Is convex-security-audit safe to install?
It is a review methodology skill; verify the package source and read the Security Audits panel on this Prism page before granting repo access to an agent.
SKILL.md
READMESKILL.md - Convex Security Audit
interface: icon_small: "./assets/small-logo.svg" icon_large: "./assets/large-logo.png" <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_3_23)"> <g clip-path="url(#clip1_3_23)"> <path d="M10.0643 12.5735C12.3769 12.3166 14.5572 11.0843 15.7577 9.02756C15.1892 14.1148 9.62646 17.3302 5.08583 15.356C4.66743 15.1746 4.30728 14.8728 4.06013 14.4848C3.03973 12.8825 2.7043 10.8437 3.18626 8.99344C4.56327 11.37 7.3632 12.8267 10.0643 12.5735Z" fill="#F3B01C"/> <path d="M3.1018 7.50072C2.16436 9.66714 2.12376 12.2034 3.27303 14.2907C-0.771507 11.2479 -0.72737 4.7362 3.2236 1.72378C3.58904 1.44535 4.02333 1.2801 4.47881 1.25494C6.3519 1.15614 8.25501 1.88006 9.58963 3.22909C6.87799 3.25604 4.23695 4.99308 3.1018 7.50072Z" fill="#8D2676"/> <path d="M10.8974 3.89562C9.52924 1.98794 7.38779 0.68921 5.04156 0.649695C9.57686 -1.40888 15.1555 1.92867 15.7629 6.86314C15.8194 7.32119 15.7452 7.78824 15.5421 8.20138C14.6948 9.92223 13.1236 11.2569 11.2876 11.7508C12.6328 9.25579 12.4668 6.20748 10.8974 3.89562Z" fill="#EE342F"/> </g> </g> <defs> <clipPath id="clip0_3_23"> <rect width="16" height="16" fill="white"/> </clipPath> <clipPath id="clip1_3_23"> <rect width="16" height="16" fill="white"/> </clipPath> </defs> </svg> --- name: convex-security-audit displayName: Convex Security Audit description: Deep security review patterns for authorization logic, data access boundaries, action isolation, rate limiting, and protecting sensitive operations version: 1.0.0 author: Convex tags: [convex, security, audit, authorization, rate-limiting, protection] --- # Convex Security Audit Comprehensive security review patterns for Convex applications including authorization logic, data access boundaries, action isolation, rate limiting, and protecting sensitive operations. ## Documentation Sources Before implementing, do not assume; fetch the latest documentation: - Primary: https://docs.convex.dev/auth/functions-auth - Production Security: https://docs.convex.dev/production - For broader context: https://docs.convex.dev/llms.txt ## Instructions ### Security Audit Areas 1. **Authorization Logic** - Who can do what 2. **Data Access Boundaries** - What data users can see 3. **Action Isolation** - Protecting external API calls 4. **Rate Limiting** - Preventing abuse 5. **Sensitive Operations** - Protecting critical functions ### Authorization Logic Audit #### Role-Based Access Control (RBAC) ```typescript // convex/lib/auth.ts import { QueryCtx, MutationCtx } from "./_generated/server"; import { ConvexError } from "convex/values"; import { Doc } from "./_generated/dataModel"; type UserRole = "user" | "moderator" | "admin" | "superadmin"; const roleHierarchy: Record<UserRole, number> = { user: 0, moderator: 1, admin: 2, superadmin: 3, }; export async function getUser(ctx: QueryCtx | MutationCtx): Promise<Doc<"users"> | null> { const identity = await ctx.auth.getUserIdentity(); if (!identity) return null; return await ctx.db .query("users") .withIndex("by_tokenIdentifier", (q) => q.eq("tokenIdentifier", identity.tokenIdentifier) ) .unique(); } export async function requireRole( ctx: QueryCtx | MutationCtx, minRole: UserRole ): Promise<Doc<"users">> { const user = await getUser(ctx); if (!user) { throw new ConvexError({ code: "UNAUTHENTICATED", message: "Authentication required", }); } const userRoleLevel = roleHierarchy[user.role as UserRole] ?? 0; const requiredLevel = roleHierarchy[minRole]; if (userRoleLevel < requiredLevel) { throw new ConvexError({ code: "FORBIDDEN", message: `Role '${minRole}' or higher required`, }); } return user; } // Permission-based check type Permission = "read:users" | "write:users" | "delete:users" | "admin:system"; const rolePermissions: Record<UserRole, Permission[]> = { user: ["read:users"], moderator: ["read:users", "w