#AI#Vibe Coding#DevOps

Vibe Coding 鉴权与租户隔离:让身份边界贯穿查询、缓存与异步任务

在路由里检查已登录不等于租户隔离。本文把可信身份、资源授权、复合外键、Row-Level Security、缓存键和后台任务统一成默认拒绝的数据边界。

本文要点

  • 主题聚焦:AI、Vibe Coding、DevOps
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年7月30日·更新于 2026年7月30日

一个常见的 AI 生成 handler 会先判断 session.user 存在,然后执行 findUnique({ where: { id: params.id } })。用户确实登录了,但只要猜到另一个组织的资源 ID,就可能读到不属于自己的记录。把 tenantId 加到请求体也不安全,因为攻击者可以改它。认证回答“你是谁”,授权回答“你能否对这个对象做这个动作”,租户隔离还要求所有数据路径都不能跨边界。

MCP Server 鉴权边界强调不要混用用户身份与服务凭证。同样原则适用于普通后端:Vibe Coding 前先画出身份来源和信任传递,不允许模型从方便取得的字段猜租户。

从可信上下文得到租户

请求进入后,认证层验证 session 或 token,产出最小 AuthContext:主体 ID、当前租户、角色/权限、认证代际与请求 ID。当前租户必须来自服务端验证过的 membership;即使 URL 是 /tenants/:tenantId,也要把参数与 membership 比对。请求 body 中的 tenantId 只可作为待验证声明,不能直接进入查询。

每个用例写成资源级规则,例如“项目成员可读当前租户项目,项目 owner 可邀请成员,只有组织管理员可删除项目”。不要把角色名散落在 controller。策略函数接受可信上下文和资源属性,默认拒绝,显式允许;所有端点包括批量导出、搜索、附件下载和管理员工具都复用同一规则。OWASP 的授权指南建议最小权限、每次请求校验并覆盖水平与垂直越权测试。

让 AI 输出授权矩阵,行是角色,列是动作,单元格给出资源条件和拒绝原因。未知条件留空并阻断生成,不要让模型自动决定“编辑者通常也能删除”。矩阵进入测试数据,策略变更和代码 diff 一起审查。

数据库中保留租户归属

租户拥有的表显式保存 tenant_id,唯一性通常以租户为作用域,例如 UNIQUE (tenant_id, slug)。子表不应只用全局 project_id 关联;用 (tenant_id, project_id) 复合外键可以阻止子记录声称属于 A 租户却指向 B 租户项目。这样即使服务查询漏条件,数据库仍能阻断一部分跨租户写入。

Repository API 强制把 TenantScope 作为参数,不提供无作用域的 findById。列表、计数、更新和删除都在同一查询里包含租户条件,不能先按 ID 读取后在内存检查,因为错误日志、缓存或计时差异已经可能泄露对象存在。批量操作返回匹配数量时,也要避免用“请求数量减更新数量”暴露其他租户数据。

PostgreSQL Row-Level Security 可以再加一道默认拒绝防线。启用 RLS 后为读写定义策略,并在事务开始使用受控会话变量传入租户;连接池复用时应使用事务局部设置并保证归还前清理。表所有者和具有 BYPASSRLS 的角色可能绕过策略,应用连接角色必须专门测试。RLS 不是授权策略的替代品,而是查询遗漏时的最后边界。

可参考MCP 多租户隔离中缓存键和请求上下文的全链路检查。若只保护数据库,cache:project:123、对象存储路径或搜索索引仍可能串租;键至少含租户和权限/版本维度,缓存命中后也不能跳过授权。

异步路径必须携带授权快照

后台任务不能只保存资源 ID 后以高权限 worker 执行。消息记录 tenant_id、发起主体、授权代际、任务类型和最小输入;worker 重新验证资源归属,并按任务契约决定是否需要实时复核权限。长任务中途撤权如何处理要显式定义,RAG 撤权传播契约提供了缓存与在途任务同时失效的思路。

服务到服务凭证只表示调用服务身份,不自动继承最终用户全部权限。若任务确需代表用户行动,采用可审计的 delegation claim,限制租户、动作、资源和过期时间。日志记录决策结果与规则版本,但不泄露其他租户资源标题或敏感字段。

共享 Prompt、生成结果或前缀缓存也要纳入边界。多租户 Prompt 前缀缓存说明了版本键和租户键缺失时的风险。任何包含租户数据的 AI 输入、检索结果、临时文件和 trace 都必须继承相同的隔离与保留策略。

用越权矩阵做负向验收

为每个动作至少测试:未登录、已登录但非成员、同角色不同租户、低角色同租户、已撤权成员、猜测存在与不存在 ID、批量混入异租户 ID。成功用例之外,断言响应、日志、缓存和数据库都没有异租户内容;404 与 403 的选择遵循统一策略,避免通过差异暴露资源存在。

数据库测试故意绕过 repository 执行缺 tenant 条件的查询,验证 RLS 阻断;以应用角色而非表 owner 运行。连接池测试连续借用同一连接服务不同租户,证明会话上下文不残留。任务测试在入队后撤权,验证既定的取消或继续规则。属性测试随机生成两组租户和资源引用,断言所有返回对象的 tenant_id 都等于上下文租户。

让 AI 修复鉴权时,提供的是授权矩阵、可信上下文类型、表归属图和负向测试,而不是一句“加权限检查”。只有身份从入口贯穿数据库、缓存、文件和 worker,并且每层都可用异租户样本证明默认拒绝,登录状态才真正变成数据隔离。

Related

相关推荐