架构概览
本页解释 Olivares AI 的结构及其原因。这是一篇说明,而非操作指南:它为你提供在安装、配置或扩展控制平面(control plane)之前所需的心智模型。如需分步指引,请参阅操作指南;如需精确契约,请参阅 API 参考与事件参考。
平台模型:一个引擎、模块、连接器
Section titled “平台模型:一个引擎、模块、连接器”Olivares AI 不是单一用途的工具。它是一个模块化平台,承袭 Grafana、Backstage 和 Kubernetes 控制平面的脉络:一个引擎(核心)加上模块再加上连接器(connector)。该产品涵盖一整套模块目录——清单(inventory)、会话(sessions)、访问图谱、治理、FinOps、评估(evaluations)、护栏(guardrails)等等——但它们全部位于同一个共享引擎之上。
该架构的根本约束是**“无需重构”规则**:引擎的设计使得目录中任何模块都可以在不触及核心或其他模块的前提下被加入。具体而言,每个新模块都:
- 从引擎消费规范化的事件与数据;
- 在共享数据模型中声明自己的实体;
- 暴露自己的 API 端点与 UI 视图。
没有任何模块会伸入另一个模块的内部,也没有任何模块为了适配自己而重塑核心。引擎在第一天就承担了多租户、事件驱动和 API 优先的前置成本,正是为了让广度可以在日后扩展而无需重新设计。同一原则也解释了构建顺序——先 CLI 引擎,再在其上构建 web:CLI 就是引擎,并通过 CLI 和 API 暴露完整功能;web 是位于同一个 API 之上的展现层,没有重复的逻辑。先构建引擎再在其上构建视觉外观,并不是一次重构。
差异化能力——带有许可对比观测(permitted-versus-observed)差异的读/写访问图谱(read/write access map)——本身就是位于共享模型之上的一个模块(模块 III),而非定制的流水线。这正是保持平台诚实的原因:旗舰功能遵守与其他一切相同的规则。
八个引擎子系统
Section titled “八个引擎子系统”引擎(核心,即“第 0 层”)是其他一切所依附的那组共享子系统。它们共有八个。
| 子系统 | 它的作用 | 它为何存在于核心 |
|---|---|---|
| 采集 + 事件总线 | 接收 OTLP 和连接器输入,将其规范化,并把事件分发给模块 | 模块对事件作出反应,彼此之间无需耦合 |
| 连接器 SDK | 一套稳定的输入/输出连接器接口——广度的支柱 | 第三方可扩展平台而无需 fork 核心 |
| 模块运行时 | 加载并运行模块:进程内编译加进程外插件 | 加入模块而无需重构或重新编译核心 |
| 通用数据模型 | 服务于整个目录的多租户实体与关系 | 一套所有模块共享并扩展的 schema |
| API(REST/gRPC)+ 以代码管理 | 全部功能皆通过 API 提供,外加一个 Terraform provider | CLI 与 web 使用同一个 API;面板可 GitOps 化 |
| AuthN/Z + 多租户 | RBAC/ABAC、组织与租户、隔离 | 事后补加权限与租户机制代价极其高昂——所以第一天就做 |
| 审计 + 完整性 | 仅追加、哈希链(hash-chained)的账本(audit ledger) | 篡改可检测性是横切关注,绝非可选 |
| 许可 / 授权 | 离线 Ed25519 许可证校验 | 自助式商用,可在隔离网络(air-gapped)下工作 |
有几处具体细节值得点明:
- 模块运行时。 核心模块被编译进二进制;进程外模块与连接器通过 gRPC 以
hashicorp/go-plugin作为插件运行。这带来故障隔离,并让模块得以在不重新编译核心的前提下被加入。 - 事件总线。 默认为进程内(Go channel)。基于 NATS 的分布式绑定是可选的,并非必需——单节点部署从不触及它。
- 以代码管理。 API 是有记录效力的契约;以代码管理这一层面增加了一个 Terraform provider,使得控制平面本身可以被声明并纳入版本控制。
- 审计 + 完整性。 该账本是仅追加且哈希链式的,并带有 Ed25519 签名的检查点。每条记录都携带序号、前一条哈希、当前哈希以及一个签名——且从不携带 PII。该账本出机有两条路径:拉取导出端点发出 CEF、LEEF、syslog、OTLP(完整的、可直接 POST 的导出请求;
otlp_envelope是其精确别名,裸 LogRecord 投影则是单独的otlp_log_record令牌)或 OCSF;而推送在配置了audit.recorded事件订阅后即真实存在,会以至少一次的语义经持久传输投递每条封存记录。参见如何将审计转发到 Splunk。 - 许可。 校验是离线的,使用 Ed25519,引擎不会为许可发起任何网络调用——这正是隔离网络运行得以可行的原因。唯一会向外发起网络请求的命令是
olivares upgrade:默认从公共仓库的 GitHub releases 获取,加--enterprise时从许可证 Worker(licenses.olivares.ai)获取——除非用--endpoint指向你自己的镜像,或用--bundle从随身携带的捆绑包安装。
关于认证与授权的细节(不透明 bearer token、首次启动设置令牌、策略决策点)请参阅安全模型;这里仅在架构依赖它们之处加以概述。
通用数据模型
Section titled “通用数据模型”一个多租户 schema 服务于整个目录。每个核心实体都携带一个 tenant_id,隔离在查询/行级别强制执行。这些核心实体涵盖组织与租户、agent、会话、模型与 provider、MCP 服务器、技能与工具、资源(数据库、服务器、存储、API)、身份、策略、成本记录、评估结果、发现项、审计事件、健康状态以及部署——以及处于核心地位的 AccessEdge。
每个模块通过类型注册表与每模块独立的表来注册自己的实体与关系,而不破坏核心。这就是数据层面“无需重构”规则背后的机制。
存储在单节点部署中起初为 SQLite(纯 Go 的 modernc 驱动,因此该二进制不需要 CGO,可在隔离网络下运行),并在多租户与扩展场景下迁移到带行级安全(row-level security)的 Postgres。
模块 III:作为模型之上视图的访问图谱
Section titled “模块 III:作为模型之上视图的访问图谱”旗舰模块是读/写访问图谱及其许可对比观测差异——最小权限漂移(least-privilege drift)。关键的架构要点在于,这是通用数据模型之上的一个视图,而非一个独立的 schema。该图谱由 AccessEdge 实体物化而来,而 AccessEdge 本身同时携带许可侧与观测侧,连同信号来源和一个置信级别。因此该差异是对每个其他模块所使用的同一多租户模型的一次查询。
读优先与最小数据
Section titled “读优先与最小数据”该图谱是读优先(read-first)的:它从日志、OpenTelemetry 以及(作为兜底的)eBPF 进行观测——它从不处于 agent 调用的数据路径中。它也是最小数据(minimal-data)的:它存储关系(某个 agent 读/写某个资源),从不存储载荷、密钥或 PII。这种不对称是刻意为之——高信号、低风险。
协作式路径与原生存储审计的交叉印证
Section titled “协作式路径与原生存储审计的交叉印证”保真度来自交叉印证两类相互独立的证据:
- 协作式路径——Claude Code 与 agent 通过 **OpenTelemetry(OTLP)**发出遥测,并辅以对某个服务器所暴露的工具与资源的 MCP 自省(introspection)。OTLP 接收器是核心采集的一部分,默认监听回环地址。参见接入 Claude Code。
- 原生存储审计——存储会告诉你实际发生了什么。pgAudit 在 Postgres 上逐字分类
READ与WRITE;CloudTrail 为 S3 显露readOnly;其他引擎也存在等效的原生审计。
当协作式路径与存储自身的审计在某条边(edge)上达成一致时,你就得到了一个相互印证的读/写关系。
eBPF 兜底、不可信注解与分级覆盖
Section titled “eBPF 兜底、不可信注解与分级覆盖”还有三项特性使该图谱可信而非天真:
- eBPF / Tetragon 是非协作式的兜底。 对于不配合协作的路径,一个内核级观测器在进程与主机层面提供关于读/写意图的基准事实(ground truth)。它运行于 agent 的控制之外(防规避),但对 TLS 载荷视而不见——这没关系,因为该图谱只需要关系,而不需要内容。
- MCP 注解不可信。 MCP 的只读/破坏性提示是一个有用的信号,但 MCP 规范本身指出客户端必须将其视为不可信。因此该图谱会对照其他来源来印证它们,且从不单凭一个注解就予以信任。
- 覆盖是分级的,且产品如实告知。 有些存储可被被动观测得干净(SQL 数据库、对象存储、数据仓库);有些是有损的(Mongo、向量数据库);还有些无法被被动观测(Redis、SQLite、D1)。该图谱展示置信级别(确切归因对比近似),而不是假装拥有它并不具备的精度。
查看访问图(access graph)是一个特权操作:限定于租户范围,对编辑者(editor)角色及以上可用(绝不对最低的查看者角色开放),且每一次读取都被审计。该图谱的路由——图与漂移结果——不属于稳定核心契约;它们发布在独立的 beta 模块路由参考中(服务于 /openapi.beta.json),其字段级形状则存在于类型化的 Go 与 TypeScript 接口中。许可对比观测的结果在引擎的 drift 路由(/v1/m/accessmap/drift)暴露;不存在单独的 diff 端点。稳定核心 REST 面包含 53 条路径,它们由产品自身的 OpenAPI 3.1 契约渲染,并记录在 API 参考中。完整模块清单请参阅模块目录。
同一个二进制支持若干种拓扑。有一条约束贯穿所有拓扑:数据平面(data plane)——采集器(collector)——始终运行在客户的基础设施上。这正是隐私与隔离网络运行得以可能的原因。产品没有强制遥测,控制平面默认也不产生出站流量。只有客户明确配置为跨越边界的内容才会跨越其边界——对客户模型 API 的调用、客户接入的 SIEM/webhook 输出,以及客户配置时使用的外部嵌入提供商。
默认方式。一个静态 Go 二进制承载 CLI 引擎、通过 go:embed 内嵌的 web UI(与 API 同源提供),以及作为存储的 SQLite。你交付一个制品并自托管(self-hosted)它。这是从零到图谱教程和自托管指南背后的拓扑。
面向多主机、规模化与多租户领地:边缘的采集器通过带双向 TLS 的 gRPC 推送到中心核心,存储变为 Postgres(带行级安全),事件总线运行在 NATS 上。采集器没有入站监听器——它们推送,而不提供服务——这使边缘攻击面保持最小。
在这种拓扑下一切都在本地运行,零出站(zero egress):存储是本地的,许可证离线校验。olivares upgrade 是本来唯一会联系我们的命令,在这里它改为从随身携带的捆绑包(--bundle)安装,而不是从更新通道获取。参见隔离网络安装。
托管(未来)
Section titled “托管(未来)”托管的控制平面在路线图上。即便如此,该约束依然成立:采集器仍然运行在客户的基础设施上,只有控制平面被托管。这处于设计阶段。
信任边界与许可
Section titled “信任边界与许可”在运行时拓扑之外,还有两条边界塑造着该架构:
- 连接器边界。 一个连接器从不从核心导入——它只依赖 SDK。这使第三方连接器不致污染核心,并保持许可边界的洁净。
- 许可边界。 核心、模块与 web 是 AGPL-3.0-only 的;SDK 与连接器是 Apache-2.0 的;企业版(enterprise tier)是商用的。上文所述的连接器边界正是使 Apache/AGPL 划分得以在代码中可强制执行的原因。参见开放核心与许可。
安全态势简述
Section titled “安全态势简述”该架构是设计即安全(secure-by-design)的:读优先观测(低且不对称的风险)、仅推送且无入站监听器的采集器、采集器与核心之间的双向 TLS、最小数据(只有边,从不有载荷)、通过仅追加哈希链账本实现的篡改可检测性、植根于数据模型的多租户隔离,以及没有强制遥测、控制平面默认不产生出站流量的自托管。只有客户明确配置为跨越边界的内容才会跨越其边界——对客户模型 API 的调用、客户接入的 SIEM/webhook 输出,以及客户配置时使用的外部嵌入提供商。完整分析——包括每条信任边界如何被防御,以及哪些被明确排除在范围之外——存在于安全模型与威胁模型中。