策略
策略
策略是一个运营如何控制谁能看到什么、更改什么的方式。一条策略,一个文件:授权本身(按集合、按动作,带行级 `where` 与字段掩码)、持有者可以调用的能力、速率限制,以及授权上的审批。这里的一切都在服务器上强制——是权限,不是占位符。
策略模型
访问被编写为可复用的策略——绝不是按用户的行:
- policy ——一个文件:description、
grants——{ collection: { read?, history?, create?, update?, delete? } } - teams ——团队映射:每个具名团队持有哪些策略
团队行(名称、父级、描述)来自控制台;权限来自
src/access/+teams.ts,按名称绑定
按集合与动作作对象键:read、history、create、update、delete
持有者:经由团队的人、envoy 或自动化
。映射里没有的团队行不生效。组织 管理员 绕过策略评估。
行级条件
读或历史授权带 where 与 fields ;where 使用诸如 ${requestor.id} 这样的标记。部分匹配产生 降级访问 ——行过滤器被合并进每次读取与变更的 SQL WHERE 子句,因此用户根本无法看到或触及他们授权之外的行。
标记词汇: ${requestor.id} ${requestor.team_scope_users} ——整条路径上的请求人;复杂谓词用 `$sql`。审批、步骤函数与 `authorize` 是 TS/Effect,不是表达式字符串。
字段掩码
- 属性级 ——从读取中省略、在 UI 中隐藏,并从提交的负载中剥离。
- 能力 ——应用、工具、MCP 服务器与技能在策略上授予;没被点名的就不可达。
变更可以导致什么
create | update | delete
│
▼
resolve the subject's grants for this collection/action
│
├── grant matches ─────────────────────► direct
├── grant narrows (where/fields) ──────► reduced (SQL + mask)
├── grant carries an approval ────────► gated (write-then-lock)
└── no grant ──────────────────────────► denied - 直接 ——授权匹配;变更照常进行
- 降级 ——行与字段收窄到授权的 `where` 与 `fields`
- 门控 ——写入立即生效,记录以请求 id 锁定,同时创建一份审批请求(先写后锁)
- 拒绝 ——没有授权或审批路径匹配时的拒绝回答
先写后锁,不是等批准再写
受门控的写入 不会 被放在队列里。变更在审查进行期间生效,记录保持锁定(`approval_id`),直到批准释放它们。完整生命周期——决策、超级取代、撤回、冲突——见 审批工作流。
推荐顺序
- 在 `src/access/+teams.ts` 中命名团队;审批人与持有者都使用团队。
- 为每个表面编写一条策略,按集合给出授权。
- 按团队持有策略;envoy 与自动化各自点名。
- 只在需要审查的变更上添加审批。
- 上线前用各自的预览账号测试每个角色。