模块 VII — 部署与集成
部署定义、计划、apply、回滚、退役、executor 设置和接线台账是 Business 功能。Community 对这些 API 路由返回 501,并隐藏该命令组。已保存的定义、修订、接线和操作会保留在数据库和灾难恢复备份中。以下各节描述 Business 的行为。
模块 VII 是唯一会变更客户基础设施的模块——产品的其余每个部分都是 read-first(先读取)的。 它以声明式、版本化、可回滚的操作来预置、更新和退役智能体与 MCP 服务器,并声明智能体到达 企业资源时所使用的连接方式与所引用的身份。正因为它会实施操作,其安全标准在整个产品中最高, 而实时执行被保持在一道 deny-closed 接缝之后,直到操作员显式将其预置为止。
先规划与治理,然后(也许)apply
Section titled “先规划与治理,然后(也许)apply”生命周期为 plan → apply → verify → retire,将期望状态与实际状态进行协调。真正关键的
区分是声明 ≠ 变更:
- 声明期望状态——创建、更新、回滚一份定义(也可通过 manage-as-code 的
olivares_deployment资源进行)——仅限于 control plane(控制平面),绝不触及基础设施。 plan是纯粹的 dry-run 差异计算;verify检查漂移并刷新快照。两者都不会变更。apply与retire是仅有的会变更的操作。它们是两阶段且 **deny-by-default(默认拒绝)**的: 第一阶段计算差异并请求一项绑定到 plan hash 的人工审批,期间不改变任何东西;第二阶段仅在审批为approved且 plan hash 仍然匹配时才继续——任何其他状态(pending、expired、rejected、无门控、 陈旧的 plan)都会被拒绝并记录。重新指定会改变 hash 并使审批失效(anti-TOCTOU,防时序攻击)。
会变更的 apply/retire 默认不是实时的。执行接缝(Executor)
是 deny-closed 的:在没有预置 executor 的情况下,apply/retire/plan/verify 会以 503 fail closed
(失败即拒绝)——control plane 可以声明期望状态,但无法协调到实际基础设施。一个真正的引擎
(Tofu/Terraform、GitOps、Kubernetes、Docker、Nomad、Crossplane)外加一个短时、按操作、经过证明的
凭据来源,只在操作员配置时才会接入;在此之前,该模块绝不会静默地实施操作。
在管理员接入执行器之前,Deploy 只保存部署定义,不会更改任何基础设施。接入步骤如下:
-
编写一个 JSON 文件,为每个部署目标运行时(
docker、k8s、nomad、tofu、terraform、gitops或crossplane)写一个块,并加上一个credential块。只有文件中列出的运行时会被接入。 同一主机上的 Docker 示例:{"docker": { "socket_path": "/var/run/docker.sock" },"credential": {"kind": "file","path_template": "/run/olivares/deploy/{env}-{mode}.token","ttl_seconds": 900}}每次操作时,Olivares 从
path_template读取一个短期令牌:{env}是定义的环境,{mode}是read(计划、校验)或write(应用、退役)。该目录由你已在运行的工具(例如 Vault Agent 或 SPIFFE 辅助程序)创建,令牌文件也由它写入并轮换。没有令牌时,每个操作都会被拒绝。对于 Docker,服务用户olivares还必须能打开该套接字;加入docker组即授予它对该主机的 root 级访问权限。 -
让 Olivares 指向该文件。使用 deb 或 rpm 软件包时,在
/etc/olivares/olivares.env中加入这一行:终端窗口 OLIVARES_DEPLOY_EXECUTOR_CONFIG=/etc/olivares/deploy-executor.json用户
olivares必须能读取该 JSON 文件,例如属主为root:olivares、权限为0640。 -
用
sudo systemctl restart olivares重启 Olivares。如果文件无法读取或内容无效,Olivares 不会启动,并在日志中说明原因。
之后,Deploy 页面会将 声明部署 作为主要操作,计划与应用会到达运行时。每次应用和退役仍需等待审批。
实体与所声明的契约
Section titled “实体与所声明的契约”该模块声明了四个带命名空间的实体,外加作为已应用快照的核心 Deployment:
| 实体 | 角色 |
|---|---|
| definition | 期望状态——期望版本对比已应用版本、spec hash、指向核心 Deployment 的链接 |
| revision | 仅追加、不可变的 spec 历史——可回滚的来源 |
| wiring | 它所声明的 agent → resource **被许可的(permitted)**连接(即模块 III 用以对照的契约) |
| operation | 仅追加的变更管理 ledger(账本)——版本、plan hash、由谁审批、结果 |
期望 spec 是有类型的,并从结构体重新序列化得来(绝不经过操作员的 JSON 往返):未知字段会被拒绝,
会运行一道内联凭据守卫,任何以明文携带凭据材料的 spec 都会在声明阶段被拒绝。凭据仅以引用方式
传递(<scheme>:<locator>,scheme 在白名单内)——这是连接的一种属性,绝不是被存储的密钥。
它在事件总线上产生什么(模块 III 的“被许可”一侧)
Section titled “它在事件总线上产生什么(模块 III 的“被许可”一侧)”模块 VII 从不写入 access map(访问地图);模块 III 是其边的唯一写入者。在一次已提交的 apply 上,
针对每条 wiring,该模块会发布一个 policy-grant 类型的
edge.observed 事件(Source = policy),其中仅携带引用与模式(mode)。
模块 III 将其协调进自身 permitted-vs-observed(被许可 vs 被观测)差异中被许可的一侧——因此本模块
所声明的内容,恰恰就是模块 III 用来对照其所观测内容的依据。身份按智能体通过治理进行绑定:一个稳固、
唯一的非人类身份会产生一条 attributed(已归因)的边;一个共享或缺失的身份则被报告为 approximate
(近似)——标记出来,绝不伪造。