Skills Agentes

Convex Authz

Audita y refuerza la autorización de una app Convex: impersonación por identity-from-arg, checks de ownership por documento faltantes, queries públicas que filtran datos por un id del cliente y escrituras en un contenedor ajeno.

Oficial
Estrellas
59

en todo el repo

Actividad
63

0–100, la ruta de este skill

Actualizado
hace 22 días

último commit aquí

Commits
3

últimos 90 días

Contexto
2.3k tok

107 tok en reposo

Paquete
1 archivo

9 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add get-convex/agent-skills --skill convex-authz --agent claude-code

Se instala solo en este repositorio.

Qué hace

  • Escanea archivos convex/**/*.ts con regex para detectar 4 patrones de fallos de autorización
  • Aplica el patrón canónico requireIdentity/requireOwner de convex-expert.md a cada hallazgo
  • Convierte funciones públicas admin/privilegiadas en internalQuery/internalMutation si falta la base de auth
  • Verifica los cambios con npx tsc --noEmit y vuelve a escanear para confirmar 0 hallazgos
  • Reporta hallazgos agrupados por los 4 tipos con archivo:línea y el diff aplicado

Úsalo cuando

  • El usuario pide 'secure my app', 'audit auth/authz' o 'who can access this data'
  • Se quiere auditar impersonación por identity-from-arg, checks de ownership faltantes, fugas de PII o escrituras en contenedores ajenos

No lo uses cuando

  • No existe un directorio convex/ en el proyecto
  • Se busca una revisión general de código (rendimiento, esquema, validadores) — eso corresponde a convex-reviewer

Qué lo activa

Di cualquiera de estas frases y el agente debería cargar este skill.

  • “Audita la autorización de mi app Convex”
  • “Asegura mi app, ¿quién puede acceder a estos datos?”
  • “Revisa si hay impersonación o fugas de datos por id en mis queries de Convex”

SKILL.md

En inglés

Convex Authz Auditor/Hardener

A focused authz specialist, not a general reviewer: it finds and fixes the four shapes that account for the largest real-defect cluster measured against generated Convex backends (25 identity-from-arg + 13 missing-ownership-check + 6 PII-leak-by-argument = 44 of 214 confirmed defects, plus the parent-reference-on-write variant of the ownership shape that fixture measurement showed the 3-shape scan misses). It runs a deterministic scan first (objective, regex-based), then applies the canonical requireIdentity/requireOwner hardening pattern from convex-expert.md to every hit, then verifies with tsc. It does not re-derive the pattern — it applies the one already documented as the platform's canonical fix.

Workflow

  1. MANDATORY FIRST STEP — check the auth foundation exists before injecting any ctx.auth enforcement: (1) is there an auth.config.ts with a provider? (2) is there a users/identities table keyed to the auth subject (tokenIdentifier/identity.subject)? If EITHER is missing, DO NOT add requireIdentity/requireOwner — on a foundationless app ctx.auth.getUserIdentity() always returns null (enforcement is non-functional: every call 401s, or worse, the check is bypassed/miscompared against a non-subject field like an email string) and a reviewer correctly flags that as a NEW authz defect, not a fix. Instead, on a foundationless app: (a) for privileged/admin operations, convert the public query/mutation to internalQuery/internalMutation (removes public reachability entirely — safe and foundation-free, no ctx.auth needed), and (b) tell the user: 'this app has no auth foundation; run /add auth or the auth setup first, then re-run convex-authz to add per-user ownership checks.' Do not run steps 1-3 below against public functions on a foundationless app beyond this internalize-and-defer move. Only when the foundation exists (both auth.config.ts and a subject-keyed users table are present) do you proceed to inject requireIdentity/requireOwner in steps 1-3.
  2. SCAN (deterministic, objective-first): for every convex/**/*.ts file (skip convex/_generated/ and .d.ts), grep for the four shapes: (a) identity-from-arg: a public query(/mutation( object whose args block declares userId/actorId/ownerId/authorId/accountId typed v.id(...), where the function's whole block (args + handler) has zero ctx.auth reference. Regex: /\b(userId|actorId|ownerId|authorId|accountId)\s*:\s*v\.id\(/ inside an args: { ... } block paired with an absent /\bctx\.auth\b/ anywhere in the enclosing (query|mutation)\(\s*\{ ... } block (word-boundary excludes internalQuery/internalMutation by construction). (b) missing-ownership-check: a public query(/mutation( whose handler loads a document via ctx.db.get(args.<xId>) (an _id-typed arg) and then calls ctx.db.patch/ctx.db.delete/ctx.db.replace on that same id, or returns the doc's fields directly, with no comparison of any <doc>.<ownerField> against an identity value anywhere in the block (no ===/!== involving identity.subject or a ctx.auth derived value). (c) PII-leaking public query: a public query( whose returns (or the raw doc it returns) includes a sensitive-looking field (email, revenue, ssn, password, token, auditLog, dashboard-shaped aggregate) and the query is parameterized by a client-supplied id with no ctx.auth check gating access to that id's own scope. (d) parent-reference ownership on write: a public mutation( whose args include a v.id(...) of a parent/container table (projectId, boardId, teamId, orgId, listId, folderId, conversationId, accountId, ...) that the handler uses as a foreign key in a ctx.db.insert/ctx.db.patch — attaching or moving a child row into that container — without verifying the caller owns (or is a member of) the referenced parent doc. Creating a row inside someone else's container is the same defect as mutating their row: fixing WHO the caller is (shape a) does not fix WHERE they may write. After handling shapes a-c, re-audit every REMAINING v.id(...) arg in every public mutation for this shape — shape-a fixes routinely leave the parent id arg behind, still unchecked. Report every hit with file, line, and which of the 4 shapes matched — this is the objective, model-independent baseline; do not skip it in favor of jumping straight to judgment.
  3. HARDEN (foundation-having apps only — see step 0): for each hit, apply the canonical pattern from content/convex-expert.md verbatim — do not invent a new helper. Add (if absent) convex/model/auth.ts exporting requireIdentity(ctx) (throws 401 if ctx.auth.getUserIdentity() is null; returns the identity) and requireOwner(ctx, doc) (throws 404 if doc is null, throws 403 if doc.ownerId !== identity.subject, else returns doc). Rewrite each flagged function: replace the client-supplied identity arg with requireIdentity(ctx); wrap each _id-keyed read/mutate with requireOwner(ctx, await ctx.db.get(args.xId)) before touching the row; scope each PII-returning query through requireIdentity/requireOwner (or an explicit staff/role check) before it reads outside the caller's own scope; for each shape-(d) hit, load the referenced parent doc and apply requireOwner(ctx, parent) (or the schema's membership check — e.g. participantIds.includes(user._id) — when the container models members as an array) BEFORE inserting/patching the child row. When the schema keys ownership by a users row id rather than the raw subject, resolve the caller's users row first (via the subject-keyed index) and compare against user._id — comparing an Id<"users"> field to identity.subject never matches and silently breaks enforcement. Never widen scope — an internal/admin function that legitimately operates on an arbitrary user stays internalQuery/internalMutation, never public; leave it unflagged and unchanged.
  4. VERIFY: run npx tsc --noEmit (or the project's typecheck script) after edits; a hardening pass that doesn't typecheck is not done. Then re-run the step-1 scan to confirm 0 remaining hits (the fixed shapes no longer match the regexes because ctx.auth now appears in-block and ownership comparisons now exist).
  5. Report findings grouped by the 4 rule shapes with file:line, explain why each is exploitable (who could impersonate whom / read whose data), and show the concrete diff applied (or, on a foundationless app, the internalize-and-defer diff plus the auth-setup nudge) — never just describe the fix in prose.

Rules

  • MANDATORY FIRST STEP: before injecting requireIdentity/requireOwner, verify the auth foundation exists — an auth.config.ts with a provider AND a users/identities table keyed to the auth subject. If either is missing, do not add ctx.auth-based enforcement (it's non-functional or mismatched and creates a NEW authz defect); instead convert flagged public admin/privileged functions to internalQuery/internalMutation and tell the user to run auth setup first, then re-run convex-authz.
  • Scan objectively before judging — run the 4 deterministic greps first; don't skip straight to LLM judgment, and don't let a clean scan stop you from still eyeballing internal/admin exemptions.
  • Identity always comes from ctx.auth, never from a client-supplied argument — the one legitimate exception is an internalQuery/internalMutation/internalAction that is never exposed publicly.
  • Every read or mutate keyed by an _id argument must verify ownership server-side (requireOwner or an inlined equivalent comparison) before touching the row — being logged in is not the same as owning this row.
  • Any v.id(...) argument a public mutation uses as a foreign key when inserting or moving a row must have the referenced parent's ownership (or membership) verified against the caller first — creating a child row inside someone else's project/board/account is the same defect as mutating their row, and it survives an identity-from-arg fix unless checked separately.
  • Never leave a public query that returns PII/financial/audit data reachable by an unauthenticated or cross-account client-supplied id.
  • Reuse requireIdentity/requireOwner from content/convex-expert.md verbatim — do not fork a parallel helper or invent new error semantics.
  • Always verify with tsc after hardening; a fix that doesn't typecheck is not shipped.
  • This is a targeted authz pass, not a general code review — do not expand scope into performance/schema/validator findings; hand those to convex-reviewer.
  • SKIP entirely when there is no convex/ directory in the project.

Reproducido de get-convex/agent-skills bajo licencia Apache-2.0. Leer esta página en markdown.

Archivos

1 archivo en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

Antes de instalar

Requiere un proyecto con directorio convex/; para inyectar requireIdentity/requireOwner necesita auth.config.ts con proveedor y una tabla users/identities indexada por el subject.

Detalles

Creador
get-convex
Categoría
Seguridad
Licencia
Apache-2.0
Recursos incluidos
Solo SKILL.md
Código fuente
Ver SKILL.md

Más de get-convex/agent-skills

Este repo incluye 33 skills. Si instalas uno, normalmente ya tienes los demás. Ver el pack agent-skills entero y su comando de instalación

Diseña y construye backends reactivos y type-safe de nivel producción en Convex: schema, queries/mutations/actions, índices, auth, storage, scheduling, multiplayer en tiempo real y workflows LLM/agentes.

Costo de contexto al activarse
972 tok
Tamaño del paquete
1 archivo
Última actualización
hace 22 días
Oficialdesarrollo apis

Levanta un template Next.js + Convex barebones a partir de una idea en una frase.

Costo de contexto al activarse
1.1k tok
Tamaño del paquete
3 archivos
Última actualización
hace 22 días
Oficialdesarrollo apis

Especialista en el backend de Convex: código dentro de convex/ (funciones, schemas, índices, queries, mutations, actions, endpoints HTTP, cron jobs, storage, auth y componentes).

Costo de contexto al activarse
1.1k tok
Tamaño del paquete
1 archivo
Última actualización
hace 22 días
Oficialbases de datos

Añade un backend de agente de IA / RAG (@convex-dev/agent) a la app Convex.

Costo de contexto al activarse
430 tok
Tamaño del paquete
1 archivo
Última actualización
hace 29 días
Oficialdesarrollo apis

Construye componentes Convex reutilizables con tablas aisladas y APIs de cara a la app. Útil para nuevos componentes, módulos de backend reutilizables, integraciones o límites de componentes.

Costo de contexto al activarse
2.6k tok
Tamaño del paquete
7 archivos
Última actualización
el mes pasado
Oficialherramientas desarrollo

Convex es la plataforma backend TypeScript reactiva y con tipos seguros de extremo a extremo: base de datos, funciones, scheduling, storage, auth y sync en tiempo real, ideal para prototipos y producción a escala.

Costo de contexto al activarse
2.4k tok
Tamaño del paquete
1 archivo
Última actualización
el mes pasado
Oficialbases de datos

Skills relacionados

Barreras de seguridad para comandos destructivos (gstack).

Costo de contexto al activarse
879 tok
Tamaño del paquete
4 archivos
Última actualización
el mes pasado
Permisos
seguridad

Cso

134k

Modo Chief Security Officer: auditoría de seguridad centrada en infraestructura, con OWASP Top 10, modelado de amenazas STRIDE y verificación activa.

Costo de contexto al activarse
19.2k tok
Tamaño del paquete
6 archivos
Última actualización
el mes pasado
Permisos
seguridad

Guard

134k

Modo de máxima seguridad: avisos ante comandos destructivos más restricción de ediciones a un directorio concreto (gstack).

Costo de contexto al activarse
850 tok
Tamaño del paquete
2 archivos
Última actualización
el mes pasado
Permisos
seguridad