用途
convex-authz 是一个专注于 Convex 后端授权(authz)问题的审计与加固技能,不是通用代码审查工具。它针对在生成式 Convex 后端中实测出现频率最高的四类缺陷进行定位与修复。据资料说明,这四类形态在 214 个已确认缺陷中合计占 44 个(25 个身份来自参数、13 个缺少所有权检查、6 个通过参数泄露 PII),此外还包括写入时父级引用归属这一变体,而仅扫描三种形态会漏掉该变体。
主要能力
该技能追踪四种缺陷形态:
- identity-from-arg(身份来自参数):公开的 query/mutation 在 args 中声明 userId/actorId/ownerId/authorId/accountId 且类型为 v.id(...),而整个函数块(args 与 handler)中没有任何 ctx.auth 引用。
- missing-ownership-check(缺少所有权检查):公开 query/mutation 的 handler 通过 ctx.db.get(args.<xId>) 读取文档后,对同一 id 执行 ctx.db.patch/delete/replace,或直接返回该文档字段,而整块中没有将文档的 ownerField 与身份值进行比较。
- PII-leaking public query(泄露 PII 的公开查询):公开 query 的返回值或其返回的原始文档包含敏感字段(如 email、revenue、ssn、password、token、auditLog、仪表盘聚合),且该查询以客户端提供的 id 为参数,没有任何 ctx.auth 检查来限制访问该 id 所属范围。
- parent-reference ownership on write(写入时的父级引用归属):公开 mutation 的 args 含父/容器表的 v.id(...)(如 projectId、boardId、teamId、orgId、listId、folderId、conversationId、accountId 等),handler 将其作为外键用于 ctx.db.insert/patch(把子行挂到或移入该容器),却未验证调用者拥有或是所引用父文档的成员。
使用方式
技能规定了强制流程:
- 第一步(强制):在注入任何 ctx.auth 校验前,先确认认证基础是否存在——(1) 是否有带 provider 的 auth.config.ts;(2) 是否有以认证主体(tokenIdentifier/identity.subject)为键的 users/identities 表。若任一缺失,不要添加 requireIdentity/requireOwner。在无基础的应应中:(a) 对特权/管理员操作,把公开 query/mutation 转为 internalQuery/internalMutation(彻底移除公开可达性,安全且无需 ctx.auth);(b) 告知用户先运行 /add auth 或完成认证配置,再重新运行 convex-authz 添加按用户的所有权检查。
- 扫描:对每个 convex/**/*.ts 文件(跳过 convex/_generated/ 与 .d.ts)用 grep 匹配上述四种形态,报告每个命中项的文件、行号与匹配形态,作为不依赖模型的客观基线。
- 加固(仅限有认证基础的应用):逐字应用 content/convex-expert.md 中的规范模式,不要自创新 helper。添加(若不存在)convex/model/auth.ts,导出 requireIdentity(ctx)(为空时抛 401,返回 identity)与 requireOwner(ctx, doc)(doc 为 null 抛 404,doc.ownerId !== identity.subject 抛 403,否则返回 doc)。重写每个被标记函数:以 requireIdentity(ctx) 替换客户端提供的身份参数;在改动行前用 requireOwner(ctx, await ctx.db.get(args.xId)) 包裹每个以 _id 为键的读写;在读取调用者自身范围之外前,为返回 PII 的查询加上 requireIdentity/requireOwner(或显式员工/角色检查);对形态 (d) 的命中,在插入/修补子行前先加载被引用的父文档并应用 requireOwner(ctx, parent)(或 schema 的成员检查,如 participantIds.includes(user._id))。当 schema 以 users 行 id 而非原始 subject 作为所有权键时,先通过主体键索引解析调用者的 users 行,再比较 user._id。绝不扩大范围:合法操作任意用户的内部/管理员函数保持 internalQuery/internalMutation,保持公开即为错误。
- 验证:编辑后运行 npx tsc --noEmit(或项目的类型检查脚本);不通过类型检查的加固不算完成。随后重跑扫描,确认 0 个剩余命中。
- 报告:按四种规则形态分组,给出 file:line,解释每个问题为何可被利用(谁可冒充谁 / 读取谁的数据),并展示实际应用的 diff(或在无基础应用上展示 internalize-and-defer 的 diff 及认证配置提示),不要只用文字描述修复。
适用场景与限制
适用于项目中存在 convex/ 目录的 Convex 应用,用于定向的授权加固。项目中没有 convex/ 目录时应完全跳过。该技能不做通用代码审查,不扩展到性能、schema 或 validator 问题,这些问题应交给 convex-reviewer。当应用缺少认证基础时,技能限制其动作:不做基于 ctx.auth 的强制校验,改为转换为内部函数并提示先完成认证配置。关于收费、价格等信息,资料中暂未提供。