跳转到内容

在 Olivares 下运行 Claude Code(联合部署)

这是 Anthropic 优先这一叙事中的 Operate(操作) 那一半:不仅观察和治理 Claude Code, 还要指挥它。控制平面启动一个真实的 claude 进程,将其 I/O 桥接为受治理的流,将每一次生命周期 转换锚定在审计账本中,并将其拆除——在一个共享工作区之上,从 API/CLI(以及后续的门户)进行, 无需 SSH。本页在一台 Linux 主机上以四种拓扑联合部署这两半,默认安全。

关于协作式观察路径(OTLP 遥测 → access map),见 连接 Claude Code;关于治理路径(将 PreToolUse 钩子用作 PEP), 见 govern-claude-code 示例。 本页讲的是联合部署:让两个运行时一起跑起来。 运行时已存在后,要在提供商配置文件下启动 Claude、Codex 或 Grok,见 运行提供商会话。

  1. 可选启用(Opt-in)。 Olivares 镜像不携带 claude。在 Docker 中,当你需要时,Olivares 会把智能体工具安装到其数据卷,并通过产品完成登录;原生安装时由下文的安装附加项完成。如果你不运行 受治理的 Claude Code,就不会安装任何东西。
  2. 官方来源,绝不二次分发。 Anthropic 的条款不允许二次分发 claude 二进制文件,因此我们 从 Anthropic 官方的、经 GPG 签名的来源在安装时安装它(原生安装时为签名的 apt/dnf/apk 仓库; 镜像中为用同一把密钥校验的 Anthropic 签名发布), 做了固定(pin)并禁用了自动更新器。我们不附带任何第三方二进制文件。你也可以 自带(BYO) claude 并让引擎指向它。
# Olivares Claude Code 引擎如何指挥它 状态
1 Docker Docker 同一容器(标准镜像),procRunner 子进程 推荐(与 2 相同的受治理路径)
2 原生 原生 同一主机(systemd),procRunner 子进程 推荐,已做端到端冒烟测试
3 Docker 原生(主机) 跨命名空间——按现状无法治理 改为同址部署(见下文)
4 原生 Docker(每会话) 通过 Docker API 的每会话容器 后续工作(已记录)

两种同址(co-located)拓扑(1、2)是安全的默认选项。拓扑 2(原生)由 scripts/smoke-agentops.sh 做了端到端测试;拓扑 1 复用同一条受治理的 procRunner 路径,CI 会运行镜像的智能体运行时检查(scripts/qualify-container-agent-runtime.sh)。 拓扑 3 和 4 要求治理者与被治理者位于不同的容器中;跨该边界桥接 stdio 需要 Docker-API 访问权限 (这是引擎默认有意不获取的特权)。它们诚实的路径在 混合拓扑 中阐明。


拓扑 1 — 两者都在 Docker 中(推荐)

Section titled “拓扑 1 — 两者都在 Docker 中(推荐)”

标准引擎容器同样运行 claude:Olivares 把智能体工具安装到其数据卷,并通过产品完成登录。非 root、只读根文件系统——与基础 compose 相同的姿态,没有第二个镜像,也没有 override 文件。

先按 digest 固定引擎并校验它:

终端窗口
# verify the engine image you run (it is cosign-signed)
cosign verify docker.io/olivaresai/olivares:0.4 \
--certificate-identity-regexp '^https://github\.com/olivaresai/olivares/\.github/workflows/release\.yml@refs/tags/[0-9]+\.[0-9]+$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
export OLIVARES_IMAGE=docker.io/olivaresai/olivares@sha256:<digest>
export OLIVARES_BIND=127.0.0.1
docker compose -f deploy/compose/docker-compose.yml up -d

在控制台的 AI 工具 中,或使用 CLI:

终端窗口
olivares tool install claude
olivares tool login claude

该工具位于数据卷中,登录归属于你的组织;会话绝不会使用保存在服务器账户 home 中的登录。


拓扑 2 — 两者都原生(无 Docker)

Section titled “拓扑 2 — 两者都原生(无 Docker)”

引擎与 claude 都在主机上;systemd 运行引擎,由引擎指挥 claude。工作区位于 /var/lib/olivares/workspaces。

不要把安装脚本通过管道交给 shell。先验证该版本的签名校验和列表,检出其中指明的那个提交, 再从该检出目录运行安装脚本。这样 install.sh 及其打包文件都来自该检出,而不是某个分支。 该代码块在带 set -eu 的子 shell 中运行:任一步骤失败即停止,校验失败后绝不会运行安装脚本。

终端窗口
(
set -eu
cd "$(mktemp -d)"
ver=0.4
base=https://github.com/olivaresai/olivares/releases/download/$ver
curl -fsSLO $base/checksums.txt
curl -fsSLO $base/checksums.txt.sig
curl -fsSLO $base/checksums.txt.pem
curl -fsSLO $base/release-commit.txt
cosign verify-blob \
--certificate checksums.txt.pem --signature checksums.txt.sig \
--certificate-identity "https://github.com/olivaresai/olivares/.github/workflows/release.yml@refs/tags/$ver" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txt
grep ' release-commit.txt$' checksums.txt | sha256sum --check
git clone https://github.com/olivaresai/olivares.git
cd olivares && git checkout --detach "$(cat ../release-commit.txt)"
OLIVARES_TOPOLOGY=native OLIVARES_VERSION=$ver sh scripts/install-agentops.sh
)

它会自动检测原生拓扑,安装经过验证的引擎二进制文件(受 cosign 关卡控制的 install.sh), 从签名的 apt/dnf/apk 仓库安装 claude(带密钥指纹验证——或用 OLIVARES_CLAUDE_INSTALL=byo 跳过), 创建无登录权限的 olivares 服务用户和工作区目录,并放入经过加固的 systemd override + 环境变量示例。 它不会自动启动治理平面——是否运行由你明确决定。

安装程序接入了什么(以及为什么)

Section titled “安装程序接入了什么(以及为什么)”
  • packaging/systemd/olivares.service.d/agentops.conf —— 一个 drop-in,为被指挥的 claude 提供一个可写的 HOME 用于 ~/.claude(保留在 /var/lib/olivares 之下),确保工作区目录存在, 并重申基础单元的文件系统策略:ProtectSystem=full、ProtectHome=false、PrivateTmp=false 和 MemoryDenyWriteExecute=false(claude 运行时会做 JIT 编译,需要 W→X 内存)。主目录和 /tmp 对引擎保持可见,所选文件夹仍可访问;每个会话的 claude 及其 stdio MCP 服务器改由 产品按文件夹施加的 Landlock 隔离约束。基础单元中的所有其他加固指令依然有效。
  • /etc/olivares/agentops.env —— 会话运行时配置(令牌文件、TTL、可选的网关基础 URL、 可选的自带 claude 路径)。

随后,刻意地:

终端窗口
sudo nano /etc/olivares/agentops.env # wire the short-lived inference token (refresher)
sudo systemctl enable --now olivares # listens on every interface by default

在任一同址拓扑中步骤相同。对 CLI 进行认证,注册共享工作区,启动:

终端窗口
export OLIVARES_SERVER_URL=https://127.0.0.1:8443
export OLIVARES_TOKEN=<your-api-token>
export OLIVARES_TENANT=<your-tenant-id>
# 1) register the shared workspace (the session's working dir; jailed file API on top)
olivares agent workspace add /var/lib/olivares/workspaces/project-x --name project-x --mode rw
# 2) launch a governed session over the stream-json transport
olivares agent session create --transport stream-json \
--permission-mode acceptEdits --model opus \
--workspace <workspace-ref> --isolation native
# 3) attach to its live, bridged I/O (lossless replay from a cursor); send input; stop
olivares agent session attach <run-ref>
olivares agent session input <run-ref> --line '{"type":"user","message":{"role":"user","content":"…"}}'
olivares agent session stop <run-ref>

每一次转换(created → launched → … → stopped)都被锚定在签名的审计账本中 (olivares agent session events <run-ref>);工作区文件 API (olivares agent workspace files|get|put|…)受 jail 限制并被审计。这一切的可复现性契约是 scripts/smoke-agentops.sh, 它对一个隔离的伪造 claude 拉起原生联合部署,并断言会话端到端可被治理。


这两种拓扑将治理者与被治理者跨容器边界拆分开。要清醒地认识其代价。

拓扑 3 — Olivares 在 Docker 中,Claude 在主机上

Section titled “拓扑 3 — Olivares 在 Docker 中,Claude 在主机上”

不存在干净的受治理路径:容器化的引擎无法掌握主机命名空间中某个进程的 stdio,而受治理的传输是 stdio。 要触及主机上的 claude 就得共享主机 PID 命名空间并把挂载映射进引擎容器——这是一次范围很大、刻意为之的 去隔离,违背了把引擎封装起来的初衷。请改为同址部署:把两者都放进标准镜像(那就是拓扑 1), 或都原生运行(拓扑 2)。这是一个真实的限制,是被明说出来而非被掩盖的。

拓扑 4 — Olivares 原生,Claude 在每会话容器中

Section titled “拓扑 4 — Olivares 原生,Claude 在每会话容器中”

这是每会话全新容器隔离的天然归宿:每个会话都获得一个全新的、经过加固的 claude 容器 (工作区 bind 挂载、只读根、非 root、cap-drop),由引擎通过 Docker API 创建并拆除,stdio 经由 Docker attach/hijack 桥接。数据模型接缝已经建模了它(--isolation container 是一个有效值, 而它将要消费的执行器挂载原语已经交付)——但其背后的 runner 尚未接入,因此原生 runner 今天会拒绝该值 (见上文的提示)。

这是一项已记录的后续工作,并未在本次发布中交付。 驱动同级容器意味着授予引擎 Docker-API 访问权限 (理想情况下通过一个最小权限的 socket 代理)——本次发布有意回避的一个信任面,转而采用无 socket 的标准镜像。 选择这一拓扑就是选择更强的治理者/被治理者隔离,代价是那项 Docker-API 授权;它将在现有的 isolation=container 接缝之后到来。在那之前,安全的默认选项是同址部署。


  • 公开端口。 Docker Compose 默认在主机的所有接口 (0.0.0.0) 上公开 HTTPS 和 gRPC。 按上面的命令设置 OLIVARES_BIND=127.0.0.1,可将访问限制为本机。引擎在容器内监听 0.0.0.0;主机端口映射控制公开范围。原生/systemd 监听器也默认使用所有接口; 请配置其监听地址以限制访问。
  • 非 root,最小权限。 uid/gid 65532、只读根文件系统、cap_drop: ALL、no-new-privileges(Docker)/ 内核与命名空间的 Protect*/Restrict* 指令;主目录和 /tmp 保持可见,允许 W^X,每个会话由 Landlock 限制在自己的文件夹内(systemd)。
  • 最小数据、白名单环境。 子进程 claude 仅继承一个明确的白名单(PATH、HOME、locale……)外加内存中的 推理令牌——没有 OLIVARES_* 签名密钥,没有可能遮蔽所铸造凭据的环境态 ANTHROPIC_*/CLAUDE_CODE_*。
  • 经过验证的供应链。 引擎经 cosign 签名(验证它 / 按摘要固定);claude 从 Anthropic 的签名仓库安装, 密钥指纹被固定。安装程序拒绝运行未经验证的引擎,且没有绕过校验的开关。
  • 锚定的审计。 每一次生命周期转换和每一次工作区变更都通过 PayloadHash 被封存在哈希链式(hash-chained)、 签名的账本中——文件的字节与帧的内容从不被持久化。