跳转到内容

治理与审批(human-in-the-loop)

本页面向已连接至少一个数据源、现在需要治理 estate 的运营者: 决定谁与何物可以行动、审阅平台所呈现的内容并据此采取行动。治理位于 模块 VI(身份、权限、治理)中,建立在与 API 其余部分相同的授权核心之上, 并且受完整审计

每一项治理决策都由保护 control plane 其余部分的同一个授权核心做出。 在更改任何东西之前,先理解它的三个特性。

授权先跑 RBAC。在某租户中没有任何成员资格的 principal 会被拒绝—— 不存在隐式授予。权限按租户限定范围,处理器只对请求解析到的那个单一租户 行动,绝不对它自己重新推导出的租户行动,这从构造上消除了 confused-deputy 和 IDOR 这两类问题。

内置角色构成一个能力递增的阶梯:

角色它能做什么
viewer读取运营数据和审计轨迹
editor以上,外加写入运营数据
admin以上,外加租户 IAM——用户、成员资格、token、设置
owner租户内的全部权限

一个模块声明它自己带命名空间的权限(<namespace>:<resource>:<verb>), 而角色按动词层级被授予这些权限(viewer 映射到 read、editor 到 write、 admin 和 owner 到 admin)。因此一个新模块在不发布引擎版本的情况下 即可引入治理界面。

在 RBAC 之上,运营者可以接入一个外部 policy decision point(PDP) 用于基于属性的规则。你用单个环境变量选择引擎:

Terminal window
# Choose one. Cedar is the embedded, pure-Go primary; OPA is an over-HTTP adapter.
OLIVARES_PDP_ENGINE=cedar # or: opa | none

两个引擎都位于同一个接缝之后,而该接缝有一条决定你必须如何对其推理的不变式:

两个适配器以不同方式保持该不变式,你也据此编写策略:

  • Cedar(嵌入式、主选、pure-Go)。 你编写 forbid 规则。一条匹配的规则 即为一项收紧;空规则集意味着 RBAC 的决策成立。Cedar 中的 permit 绝不能放宽决策。
  • OPA(经 HTTP)。 你的 Rego 必须是 permit-by-defaultdefault allow := true,用 allow := false 子句表达你的拒绝)。 true 结果意味着不收紧;false、缺失结果,或任何传输错误或非 2xx 错误 均 fail closed——请求被拒绝。

一个无效的 PDP 配置只会禁用外部 PDP 并记录此事实——native ABAC 和 RBAC 继续治理。一个配置错误的策略引擎绝不会让请求处于无治理状态,也绝不会让 control plane 宕机。PDP 施加的每一项收紧都被审计。

human-in-the-loop 治理由平台所观测并呈现的内容驱动。两条流告诉运营者 什么值得做出一项决策:

模块它呈现什么
least-privilege driftIII(access map)permitted-vs-observed 差异——一项被授予的能力以无人意图的方式被使用,或一条可达但从未被行使的路径
发现项IX(安全、guardrails、取证)guardrail 和红队发现项,外加平台路由的通知流

模块 III,即 access map,是读优先(read-first)的——它通过日志、 OpenTelemetry 以及(作为非协作式内核兜底的)eBPF 进行观测, 并且绝不在 agent 的数据路径上,因此一次 collector 故障不会破坏生产。 它还是**最小数据(minimal-data)**的:它存储 agent → resource (read/write) 这一关系,绝不存储载荷、密钥或 PII。它所承载的信号对自身的置信度 (attributedapproximate)和自身的覆盖范围是诚实的。

有一类信号需要明确的治理判断。MCP 工具注解 (readOnlyHint / destructiveHint)是有用的读/写提示,但按 MCP 规范 不可信——客户端必须将其视为不可信。平台会用可信信号去佐证它们, 绝不单独信任它们;当你对一个仅依赖某条注解的 drift 项行动时,你也应如此。

设想中的治理闭环是:界面呈现(来自模块 III 的 drift、来自模块 IX 的 发现项)→ 一位经授权的运营者做出决策该决策被记入审计账本

该闭环的三个部分今天都在运行。界面是真实的——模块 III 产出 permitted-vs-observed 差异,模块 IX 产出发现项。审批引擎是真实的—— 一个受治理的审批请求针对治理模块开启(deny-closed、绑定 plan hash、设时限); 一位经授权的运营者通过决策端点审批或驳回,且职责分离、重复决策者与过期 都在服务器端强制,因此请求者绝不能决策自己的请求,过期的请求也绝不能生效。 而记录是真实且强健的——参见下文的保证。仍处于设计阶段的是完整建成的 运营者审阅控制台——一个丰富的审批队列 UI;端点和引擎已交付, 打磨后的审阅界面是模块 VI 的前进路径。

使这个闭环可信的依赖是 per-agent identity。平台的审计将活动归因于一个 凭据或角色,而非天然地归因于某个 agent;一个带连接池的共享服务账户会让归因 坍塌。因此良好的治理意味着为每个 agent 签发并强制其身份——这是从观测 (模块 III)到治理(模块 VI)的桥梁。其身份一侧围绕不透明、可撤销的第一方 凭据和一份非人类身份(non-human identities)名册构建;产品中唯一的凭据签发 原语是 opt-in 的、经证明的、被审计的,且绝不持久化所签发的 token。 关于身份、权限与治理如何跨 estate 组合,参见 模块目录

为了获得一份外部的、不可变的副本——企业审计师会索取而原生遥测无法提供的东西—— 账本以经认证的拉取导出形式暴露:

Terminal window
# Pull the signed, hash-chained ledger for offline re-verification.
# Requires a token whose role can read the audit trail (viewer and up).
curl -fsS "https://localhost:8443/v1/audit/export?format=cef" \
-H "Authorization: Bearer $OLVK_TOKEN" \
-H "X-Olivares-Tenant: $TENANT" >> /var/log/olivares/audit.cef

受支持的 format 值为 cefleefsyslogotlpotlp_envelopeotlp_log_recordocsf。 其中 otlp 输出完整的、可直接 POST 的导出请求,otlp_envelope 是它的精确别名, otlp_log_record 则是每行一条 LogRecord 的裸投影。每条记录都 携带链完整性字段,因此你的 SIEM 或 WORM 存储可以离线再验证该链。 分离式签名(detached signature)防御仅限数据库的失陷(注入、被窃的备份或副本、 一个绕过 RLS 的角色)以及检查点删除;一份离机副本才是对主机被完全失陷的控制。 关于完整的文件 tail 流水线,参见 转发审计到 Splunk

这些决策据以行动的 least-privilege drift 就是 access map 的 permitted-vs-observed 结果。zero-to-graph 教程 在演示 estate 上具体演练如何抵达它;access map 模块界面与其他一切一样, 受同样的 deny-by-default RBAC、租户范围限定和逐次读取审计的约束, 这也是读取它属于 editor 及以上操作的原因。

  • 安全模型——特权、租户范围限定、 自审计,以及最小数据态势的完整说明。
  • 威胁模型——资产、信任边界, 以及每一覆盖层能证明什么。
  • 模块目录——身份、权限与治理(模块 VI) 如何与 access map(模块 III)和发现项(模块 IX)组合。
  • 连接一个数据源——接好 drift 和发现项据以构建的信号。