EctoSpace/EctoLedger

GitHub: EctoSpace/EctoLedger

EctoLedger 是一个基于 Rust 的 AI 代理审计平台,通过哈希链签名和多级策略管控,为自主智能体的执行过程提供防篡改的可验证性与合规证明。

Stars: 2 | Forks: 0

# EctoLedger [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/c0d5cdf0f3082033.svg)](https://github.com/EctoSpace/EctoLedger/actions/workflows/ci.yml) [![许可证](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) [![版本](https://img.shields.io/badge/version-0.6.2-orange.svg)](Cargo.toml) [![Rust](https://img.shields.io/badge/rust-1.94%2B%20%7C%20edition%202024-orange.svg)](https://www.rust-lang.org) [![GitHub 议题](https://img.shields.io/github/issues/EctoSpace/EctoLedger.svg)](https://github.com/EctoSpace/EctoLedger/issues) [![最近提交](https://img.shields.io/github/last-commit/EctoSpace/EctoLedger.svg)](https://github.com/EctoSpace/EctoLedger/commits/main)

EctoLedger Logo

经加密验证的 AI agent 执行 - 防篡改、策略强制、合规就绪。

快速入门前置条件快速开始架构管理 GUISDKCLI 参考配置可验证凭证合规性项目结构

## 什么是 EctoLedger? EctoLedger 是一个 **AI agent 黑匣子记录器**。 它帮助你准确证明 AI agent 做了什么、按什么顺序、以及每个操作是否都在策略范围内。 ### 它的功能 - 在防篡改的审计轨迹中记录每一个 agent 决策和工具调用 - 在执行有风险的操作之前,通过策略和护栏进行阻止 - 导出可验证的审计证书,你可以向客户、审计员、监管机构或法院展示 ### 适用人群 - 部署运行命令、调用 API 或访问敏感数据的 AI agent 的团队 - 需要强制执行和验证 AI 行为的安全和平台团队 - 为正式的 AI 治理和外部审计做准备的合规团队 - 需要 AI 行为的机器可验证证据(而不仅仅是日志)的构建者 ### 为什么是现在? 欧盟 AI 法案及相关治理要求正在推动组织对高风险 AI 系统实现可证明的可审计性。如果一个自主工作流做出了有害或有争议的决策,“相信我们”是不够的。EctoLedger 为你提供可以独立验证的加密证据。 ![EctoLedger demo](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/cf32dcba57082035.gif) ### 工作原理(技术层面) EctoLedger 为每个 AI agent 提供一个加密密封的审计轨迹。每个动作在执行前都经过哈希链接、签名验证和策略门控。结果是一个不可变的账本,监管机构、审计员和安全团队可以检查、重放和独立验证——无需信任发行者。 **0.6.2 版本亮点:** | 能力 | 提供的功能 | |---|---| | **可插拔账本后端** | 通过 `LedgerBackend` trait 将 PostgreSQL 替换为 SQLite(开发/CI)——或任何未来的存储——;[SQLite 不支持](#sqlite-limitations) `audit`、`orchestrate`、`diff-audit`、`red-team`、`prove-audit` 或 `anchor-session` | | **Tauri 2 管理 GUI** | 毛玻璃风格桌面应用:实时仪表板、Prometheus 指标、会话浏览器、策略编辑器、Tripwire 配置、设置、证书导出 | | **Python 与 TypeScript SDK** | 类型化 REST 客户端;包含 LangChain `LedgerTool` 和 AutoGen `LedgerHook` | | **带 HMAC 签名的扩展 Webhook** | GuardDenial 和 TripwireRejection 事件以 JSON、CEF 或 LEEF 格式发送到任何 SIEM;`X-EctoLedger-Signature: sha256=` 标头确保每次交付的安全 | | **W3C 可验证凭证** | 会话完成时颁发 VC-JWT;Ed25519 签名,锚定 `did:key:`;可通过 `GET /api/sessions/{id}/vc/verify` 解析 | | **ISO 42001:2023** | 机器可读的策略包(14 项控制)和合规白皮书 | | **4 层语义护栏** | 策略引擎 → 双 LLM 护栏进程 → 严格 schema JSON 验证 → 结构化 tripwire,在每次提交前执行 | | **硬件 microVM 沙箱(仅限 Linux)** | 基于 Firecracker 的 `run_command` 意图执行隔离;通过 `scripts/setup-firecracker.sh` 快速设置;通过 `scripts/provision-firecracker.sh` 进行企业配置(自定义前缀、`/opt/ectoledger` 路径) | | **EVM 链锚定** | 通过 `anchor-session --chain ethereum` 将账本尖端哈希发布到任何兼容 EVM 的链;内置并默认启用 | | **SP1 ZK 证明** | 可证明的策略合规性,无需暴露原始事件 payload | | **`.elc` 审计证书** | 自包含、五重可验证记录;独立的 `verify-cert` 二进制文件 | | **自动签名密钥轮换** | 每 N 步轮换会话 Ed25519 密钥;`KeyRotation` 事件记录每次轮换。可通过 `AGENT_KEY_ROTATION_STEPS` 配置。 | | **动态编排器策略注入** | 通过 `ECTO_RECON_POLICY`、`ECTO_ANALYSIS_POLICY`、`ECTO_VERIFY_POLICY` 环境变量或共享 `--policy` 文件进行每角色策略覆盖 | | **可配置网络绑定** | Observer 仪表板绑定地址和端口完全可通过 `ECTO_BIND_HOST` / `ECTO_BIND_PORT` 配置——容器环境中无端口冲突 | | **硬件感知连接池** | 数据库池默认扩展至 2×CPU(5–50);可通过 `DATABASE_POOL_SIZE` 覆盖 | ## 前置条件 | 依赖项 | 用途 | 备注 | |---|---|---| | Rust 1.94+ | 所有构建 | 推荐 `rustup`(2024 版本) | | Docker | Docker 演示(`docker-compose.demo.yml`) | `--demo` 启动器模式或 SQLite 模式不需要 | | Ollama / OpenAI / Anthropic | `audit`、`orchestrate`、`red-team` | 必须至少有一个 LLM 后端可达 | | Node.js 20+ 和 npm | Tauri 2 GUI(`gui/`) | 仅在构建或运行桌面应用时需要 | ## 设计哲学 **Agent 即数据库。** Rust 进程是一个临时工作器。所有持久状态——事件日志和快照——都存在于配置的账本后端(PostgreSQL 或 SQLite)中。进程没有长期记忆;它在每次运行时从账本恢复状态。 **先验证后提交。** LLM 提出的动作在提交或执行之前,会经过严格的四层流水线: 1. **账本目标锚定。** 会话目标在创建时进行哈希处理(`goal_hash`),并在每次 `append_event` 时重新验证。事件通过 SHA-256 链接:链中任何位置的任何插入、删除或变异都可以在启动时检测到,而无需重放执行。 2. **护栏进程(双 LLM)。** 一个辅助 LLM(`GUARD_LLM_BACKEND` / `GUARD_LLM_MODEL`)在一个单独的进程(`guard-worker`)中运行,通过 `stdin`/`stdout` JSON 进行通信。它根据声明的目标评估每个提议的意图,并返回 `ALLOW` 或 `DENY: `。在生产环境中配置 `GUARD_REQUIRED=true`。 3. **输出内容扫描(混合)。** 执行观察在被追加到账本之前,会经过两轮扫描: - **正则通过:** NFKC 归一化,然后是经过调优的模式——注入短语、Unicode 同形字、零宽字符、LLM 模板标签、嵌入的动作 JSON、data/javascript URI、角色注入、base64 编码块和提示延续标记。 - **严格 schema 通过:** 每个包含 `"action"` 键的 JSON 对象都会根据带有 `#[serde(deny_unknown_fields)]` 的密封 `StrictAgentOutput` schema 进行验证。任何携带四个允许键(`action`、`params`、`justification`、`reasoning`)之外字段的对象都会立即被标记为 `strict_schema_violation`——捕获利用与有效 agent 输出结构重叠的劫持插入,如 `override_goal` 或 `system_prompt`。 - **结构化 JSON/AST 通过:** 括号深度提取加上对每个 `{...}` 候选的 `serde_json` 解析,检测正则表达式单独会遗漏的动作形状对象和目标劫持键。 - **Base64 通过:** 解码 `eyJ...` base64 候选,并在解码后的 payload 上重新运行结构检查。 **Tripwire(结构化规则):** - **路径** - 组件级 `..` 拒绝,不使用 `canonicalize()` 的归一化,符号链接逃逸检测;仅允许配置工作区下的目录。 - **网络** - 仅允许白名单域;默认强制 HTTPS(可配置)。 - **命令** - 危险 shell 结构的黑名单(`sudo`、`rm -rf` 等)。 - **理由** - 每个非完成动作都需要最低长度的理由(默认 5 个字符);空缺或缺失的理由会被立即拒绝。 Tripwire 规则(最小理由长度、要求 HTTPS、允许的路径/域、禁止的命令模式)可通过 GUI **Tripwire** 菜单或 `~/.ectoledger/tripwire.json` 配置。有关其他环境驱动的选项,请参阅下面的“硬件 microVM 沙箱”和“自动签名密钥轮换”部分。 这些层共同提高了提示注入的门槛,但不宣称绝对免疫——没有软件防御是绝对的。通过所有检查的意图被追加到哈希链账本并执行;没有任何东西被更新或删除。 ## 配置参考 所有配置均从环境变量加载(通过 `dotenvy` 可选支持 `.env` 文件)。标记为 **[必需]** 的值没有合理的默认值,必须设置才能激活所描述的功能。 ### 核心 Agent | 变量 | 默认值 | 描述 | |---|---|---| | `DATABASE_URL` | `postgres://ectoledger:ectoledger@localhost:5432/ectoledger` | 账本后端。SQLite 使用 `sqlite://ledger.db`。 | | `DATABASE_POOL_SIZE` | `2×CPU`(最小 5,最大 50) | 数据库连接池大小。自动扩展以适应可用的 CPU 核心。 | | `LLM_BACKEND` | `ollama` | 主 LLM 后端:`ollama`、`openai`、`anthropic`。 | | `OLLAMA_BASE_URL` | `http://localhost:11434` | Ollama 服务器 URL。 | | `OLLAMA_MODEL` | `mistral` | 用于 agent 推理的模型。 | | `OPENAI_API_KEY` | - | **[openai 必需]** OpenAI API 密钥。 | | `ANTHROPIC_API_KEY` | - | **[anthropic 必需]** Anthropic API 密钥。 | | `AGENT_MAX_STEPS` | `20` | 每个会话的最大认知循环步数。 | | `AGENT_SNAPSHOT_INTERVAL` | `50` | 自动状态快照之间的步数。 | | `AGENT_LLM_ERROR_LIMIT` | `5` | 中止会话前的连续 LLM 错误次数。 | | `AGENT_GUARD_DENIAL_LIMIT` | `3` | 中止前的连续护栏拒绝次数。 | | `AGENT_JUSTIFICATION_FAILURE_LIMIT` | `3` | 中止前的连续 schema 失败次数。 | | `AGENT_TOKEN_BUDGET_MAX` | 无限制 | 每个会话的最大近似 token 预算。 | | `AGENT_KEY_ROTATION_STEPS` | 禁用 | Ed25519 签名密钥轮换之间的步数。 | | `AGENT_ALLOWED_DOMAINS` | `[]` | 允许的 `http_get` 域的逗号分隔列表。 | ### 护栏进程 | 变量 | 默认值 | 描述 | |---|---|---| | `GUARD_REQUIRED` | `true` | 如果缺少护栏 LLM 配置,则中止启动。仅在开发时设置 `false`。 | | `GUARD_LLM_BACKEND` | - | **[当 `GUARD_REQUIRED=true` 时必需]** 护栏 LLM 后端:`ollama`、`openai`、`anthropic`。 | | `GUARD_LLM_MODEL` | | **[当 `GUARD_REQUIRED=true` 时必需]** 护栏 LLM 模型名称。 | ### Observer 仪表板与 API | 变量 | 默认值 | 描述 | |---|---|---| | `OBSERVER_TOKEN` | 自动生成 | 仪表板 API 的 Bearer token。如果未设置,首次运行时打印到 stdout。 | | `ECTO_BIND_HOST` | `0.0.0.0` | 绑定仪表板监听器的网络接口。回环仅使用 `127.0.0.1`。 | | `ECTO_BIND_PORT` | `3000` | 仪表板监听器的 TCP 端口。覆盖以避免多实例部署中的冲突。 | | `SCANNER_SENSITIVITY` | `medium` | 输出扫描器级别:`low`(仅结构)、`medium`(默认)、`high`(最广)。 | ### Webhook / SIEM 出站 | 变量 | 默认值 | 描述 | |---|---|---| | `WEBHOOK_URL` | 禁用 | 安全事件 POST 的目标 URL。启用出站时必需。 | | `WEBHOOK_BEARER_TOKEN` | - | 添加到每个 POST 的 `Authorization: Bearer ` 标头。 | | `WEBHOOK_HMAC_SECRET` | 禁用 | 设置后,每个 POST 包含 `X-EctoLedger-Signature: sha256=` 用于接收端验证。 | | `WEBHOOK_RATE_LIMIT_PER_SECOND` | `10` | 每个 URL 每秒的最大出站 webhook 传递数。 | | `WEBHOOK_INCLUDE_GUARD` | `true` | 在出站中包含 `GuardDenial` 事件。 | | `WEBHOOK_INCLUDE_TRIPWIRE` | `true` | 在出站中包含 `TripwireRejection` 事件。 | | `SIEM_FORMAT` | `json` | 输出格式:`json`、`cef`(ArcSight)、`leef`(IBM LEEF 2.0)。 | ### EVM 链锚定 | 变量 | 默认值 | 描述 | |---|---|---| | `EVM_RPC_URL` | - | **[EVM 锚定必需]** JSON-RPC 端点(例如 `https://mainnet.infura.io/v3/`)。 | | `EVM_CHAIN_ID` | - | **[必需]** EIP-155 链 ID(1 = 以太坊主网,137 = Polygon 等)。 | | `EVM_CONTRACT_ADDRESS` | - | **[必需]** 已部署的 `EctoLedgerAnchor` 合约地址(校验和格式)。 | | `EVM_PRIVATE_KEY` | - | **[必需]** 用于签署锚定交易的十六进制编码私钥。 | ### Firecracker microVM 沙箱 | 变量 | 默认值 | 描述 | |---|---|---| | `ECTO_FC_BINARY` | `/usr/local/bin/firecracker` | Firecracker 二进制文件路径。设置此项即选择加入沙箱模式。 | | `ECTO_FC_KERNEL` | `/opt/ectoledger/vmlinux` | Linux 内核镜像路径(ELF 或 Image 格式)。 | | `ECTO_FC_ROOTFS` | `/opt/ectoledger/rootfs.ext4` | 根文件系统 ext4 镜像路径。 | | `ECTO_FC_VCPUS` | `1` | 每个 microVM 的 vCPU 数量。 | | `ECTO_FC_MEM_MIB` | `128` | 每个 microVM 的内存(MiB)。 | | `ECTO_FC_TIMEOUT_SECS` | `30` | 硬性执行超时(秒)。 | ### 编排器策略注入 | 变量 | 默认值 | 描述 | |---|---|---| | `ECTO_RECON_POLICY` | 内置 | 覆盖内置 Recon 子 agent 策略的 TOML 策略文件路径。 | | `ECTO_ANALYSIS_POLICY` | 内置 | 覆盖内置 Analysis 子 agent 策略的 TOML 策略文件路径。 | | `ECTO_VERIFY_POLICY` | 内置 | 覆盖内置 Verify 子 agent 策略的 TOML 策略文件路径。 | ## 架构 认知循环是一个严格的流水线:**感知 → 提议 → 验证 → 提交 → 执行。** ``` flowchart LR Perceive[Perceive State] Propose[Propose Intent] Policy[Policy Engine] Guard[Guard Process] Tripwire[Tripwire] Commit[Commit to Ledger] Execute[Execute Side Effect] LLM[Primary LLM] DB[(Ledger Backend\nPostgres · SQLite)] Host[Host] Perceive -->|restore from backend| Propose Propose -->|LLM JSON| LLM LLM --> Propose Propose --> Policy Policy --> Guard Guard --> Tripwire Tripwire -->|allowed only| Commit Commit -->|hash-chain + Ed25519| DB Commit --> Execute Execute -->|run / read / http| Host Execute -->|observation scanned| DB ``` 1. **感知** - 从账本恢复 agent 状态(最新快照 + 重放事件)。 2. **提议** - 将状态发送到主 LLM;接收单个 JSON 意图(`run_command`、`read_file`、`http_get`、`complete`)。 3. **验证** - 策略引擎(如果设置了 `--policy`),然后是护栏进程(单独的二进制文件),然后是 Tripwire;拒绝或接受。 4. **提交** - 验证目标哈希,将动作追加到账本(哈希链、Ed25519 签名),然后运行副作用。 5. **执行** - 运行命令,读取文件,或执行 HTTP GET;扫描观察;追加到账本。循环直到 `complete` 或达到 `max_steps`。 ## 可插拔账本后端 `LedgerBackend` trait(`crates/ledger-api`)将 agent 运行时与任何特定存储引擎解耦。EctoLedger 提供两个生产就绪的实现: | 后端 | 连接字符串 | 最适合 | |---|---|---| | **PostgreSQL**(`PostgresLedger`) | `postgres://user:pass@host/db` | 生产、多 agent、高吞吐量 | | **SQLite**(`SqliteLedger`) | `sqlite://ledger.db` | 本地开发、CI、单机审计 | #### SQLite 限制 通过 `DATABASE_URL` 在运行时切换后端: ``` # PostgreSQL (默认) DATABASE_URL=postgres://ectoledger:ectoledger@localhost:5432/ectoledger cargo run -- serve # SQLite - 零基础设施,零配置 DATABASE_URL=sqlite://ledger.db cargo run -- serve ``` `LedgerBackend` trait 提供了一个最小的、游标式接口(简化版——请参阅 [`crates/ledger-api/src/lib.rs`](crates/ledger-api/src/lib.rs) 获取包含签名密钥、序列范围和管理操作的完整生产 trait): ``` pub trait LedgerBackend: Send + Sync { async fn create_session(&self, new: NewSession) -> Result<(Session, Vec), LedgerError>; async fn append_event(&self, session_id: Uuid, payload: RawPayload, signing_key: &SigningKey, seq: i64) -> Result; async fn seal_session(&self, session_id: Uuid) -> Result<(), LedgerError>; async fn get_events_by_session(&self, session_id: Uuid) -> Result, LedgerError>; async fn list_sessions(&self, limit: i64) -> Result, LedgerError>; async fn verify_chain(&self, from: i64, to: i64) -> Result; async fn prove_compliance(&self, session_id: Uuid) -> Result; } ``` 第三方可以实现此 trait 以添加自定义后端(DynamoDB、FoundationDB 等),而无需修改 EctoLedger 本身。 ### 扩展性考量 PostgreSQL 支持水平扩展,但有以下注意事项: - **SSE fanout** 使用 PostgreSQL `LISTEN/NOTIFY` 跨实例唤醒订阅者(请参阅 `pg_notify` 模块)。 - **审批状态** 可以持久化到 `pending_approvals` 表以实现跨实例可见性。 - **会话所有权** 使用每会话咨询锁来防止重复的认知循环。 有关完整的水平扩展指南,请参阅 [`docs/SCALING.md`](docs/SCALING.md)。 ## 零摩擦设置 ### 额外环境变量 - `ECTO_FC_BINARY`、`ECTO_FC_KERNEL`、`ECTO_FC_ROOTFS` – 启用 Firecracker 沙箱所需的路径。至少设置 `ECTO_FC_BINARY` 以选择加入;如果文件缺失或在非 Linux 平台上,agent 将发出警告。 - `ECTO_FC_VCPUS`、`ECTO_FC_MEM_MIB`、`ECTO_FC_TIMEOUT_SECS` – microVM 大小和执行超时的可选调优参数。 - `AGENT_KEY_ROTATION_STEPS` – 自动会话签名密钥轮换之间的认知循环步数的正整数。如果未设置或为零,则禁用轮换。每次生成新密钥时都会追加一个 `KeyRotation` 账本事件。 ### Firecracker microVM - 自动配置 提供了两个配置脚本: | 脚本 | 用例 | |---|---| | `scripts/setup-firecracker.sh` | dev/CI 快速设置 - 安装到 `~/.local`(无需 root)或 `/usr/local` | | `scripts/provision-firecracker.sh` | 企业设置 - 安装到 `/opt/ectoledger`、自定义 FC 版本、systemd 就绪 | `scripts/setup-firecracker.sh` 脚本在任何支持 KVM 的 Linux 主机(x86\_64 和 aarch64)上自动化整个 Firecracker 设置。它下载 Firecracker 二进制文件、最小 Linux 内核镜像和兼容的 rootfs,然后打印所需的确切环境变量导出: ``` # 一次性设置(对于系统范围路径以 root 身份运行,或对于 ~/.local 以普通用户身份运行) sudo bash scripts/setup-firecracker.sh # 导出脚本打印的变量,然后: cargo build --release --features sandbox-firecracker # 或使用预构建的 Linux 二进制文件: ECTO_FC_BINARY=/usr/local/bin/firecracker \ ECTO_FC_KERNEL=/opt/ectoledger/vmlinux \ ECTO_FC_ROOTFS=/opt/ectoledger/rootfs.ext4 \ ./ectoledger-linux audit "" ``` 以非 root 用户运行时,资产安装到 `~/.local/bin` 和 `~/.local/opt/ectoledger`,无需 `sudo`。该脚本验证架构、检查 KVM 可用性、验证二进制校验和,并在完成时打印一个可 source 的导出块。 EctoLedger 是**自部署的**——无需手动数据库创建、迁移工具或配置文件。 **PostgreSQL 模式**(默认):如果 `DATABASE_URL` 未设置,二进制文件默认为 `postgres://ectoledger:ectoledger@localhost:5432/ectoledger`。它检查名为 `ectoledger-postgres` 的 Docker 容器,如果不存在则启动一个,轮询直到就绪,然后自动运行迁移并创建创世块。 **SQLite 模式**:设置 `DATABASE_URL=sqlite://ledger.db`。无 Docker、无外部进程、无迁移工具。数据库文件在首次运行时创建。 如果 `OBSERVER_TOKEN` 未设置,则生成一个随机 token 并在启动时与仪表板 URL 一起打印——将其用作 `?token=…` 或在 `Authorization` 标头中使用。 ## 快速开始 **macOS:** ``` git clone https://github.com/EctoSpace/EctoLedger.git cd EctoLedger ./ectoledger-mac ``` **Linux:** ``` git clone https://github.com/EctoSpace/EctoLedger.git cd EctoLedger ./ectoledger-linux ``` **Windows (PowerShell):** ``` git clone https://github.com/EctoSpace/EctoLedger.git cd EctoLedger .\ectoledger-win.ps1 ``` 就是这样。启动器脚本: 1. 检查前置条件(`cargo`、`node`、`npm`;如果 Ollama 未运行则发出警告) 2. 首次运行时使用安全的开发默认值创建 `.env` 3. 构建 Rust 二进制文件(后续运行跳过——快速重启) 4. 为 GUI 安装 npm 包(`gui/node_modules`) 5. 在 `http://127.0.0.1:3000` 启动后端服务器 6. 打开具有热重载功能的 Tauri 桌面 GUI 按 **Ctrl+C** 干净地停止所有内容。 ### 🚀 尝试零配置演示 想在不配置数据库或 API 密钥的情况下看到 EctoLedger 的实际效果吗?使用 `--demo` 标志运行启动器: ``` # macOS ./ectoledger-mac --demo # Linux ./ectoledger-linux --demo # Windows (PowerShell) .\ectoledger-win.ps1 -demo ``` **会发生什么?** 启动器在单独的端口上启动一个隔离的嵌入式 PostgreSQL 实例,自动检测你的 LLM,并设置 `ECTO_DEMO_MODE=true`,以便后端使用与你的正常数据完全独立的数据库。阅读完整的[演示架构指南](docs/demo-README.md)了解详情。 **LLM 选择(自动,按优先顺序):** | 条件 | 结果 | |---|---| | 环境中有 `OPENAI_API_KEY` | 使用 OpenAI —— 无需本地模型 | | 环境中有 `ANTHROPIC_API_KEY` | 使用 Anthropic —— 无需本地模型 | | 两个密钥均未设置 | 检查 Ollama;如果缺失则自动安装,启动守护进程,拉取 `qwen2.5:0.5b`(约 500 MB,一次性下载) | **数据隔离:** 演示 PostgreSQL 在端口 5433 上运行,数据库为 `ectoledger_demo`,与你的正常数据分开存储(Linux 上为 `~/.local/share/ectoledger/postgres-demo`,macOS 上为 `~/Library/Application Support/ectoledger/postgres-demo`)。同时使用 `--reset-db --demo` 来擦除它。 ### 🐳 Docker 演示 无需 Rust 工具链、Node.js、Ollama —— 只需 Docker。一条命令从 GitHub Container Registry 拉取预构建镜像并启动完整的后端堆栈: ``` docker compose -f docker-compose.demo.yml up ``` 然后在浏览器中打开 **http://localhost:3000**。 | 组件 | 镜像 | 备注 | |---|---|---| | PostgreSQL 17 | `postgres:17-alpine` | 隔离 DB,数据持久化在命名的 Docker 卷中 | | Ollama | `ollama/ollama:latest` | 首次启动时自动拉取 `qwen2.5:0.5b` | | EctoLedger | `ghcr.io/ectospace/ectoledger:latest` | 预构建的发布二进制文件,几秒钟内拉取完成 | 停止并删除所有数据: ``` docker compose -f docker-compose.demo.yml down -v ``` **从源代码构建**(可选 —— 仅在你想测试本地代码更改时): ``` docker compose -f docker-compose.demo.yml -f docker-compose.build.yml up --build ``` **通过 `make` 简写**(macOS/Linux): | 命令 | 描述 | |---|---| | `make start` / `make` | 构建 + 启动后端 + GUI(默认) | | `make setup` | 仅首次构建和安装,不启动服务器 | | `make rebuild` | 强制重建然后启动 | | `make backend` | 仅后端(无 GUI) | | `make reset-db` |擦除嵌入式 Postgres 数据目录(修复部分首次运行后的身份验证失败) | | `make test` | 运行 Rust 单元测试 | | `make test-integration` | 针对临时 Postgres 的集成测试(需要 Docker) | | `make check` | 类型检查 Svelte/TypeScript GUI | | `make clean` | 删除所有构建产物 | **自定义你的设置** - 编辑 `.env`(首次启动时自动创建): ``` # 使用 OpenAI 代替 Ollama LLM_BACKEND=openai OPENAI_API_KEY=sk-... # 启用生产 guard GUARD_REQUIRED=true GUARD_LLM_BACKEND=ollama GUARD_LLM_MODEL=llama3 # 启用 SIEM webhook egress WEBHOOK_URL=https://your-siem.example.com/events ``` ## 管理 GUI `gui/` 包含一个 **Tauri 2 + Svelte 5** 桌面应用程序——一个用于 macOS、Windows 和 Linux 的原生二进制文件,通过 HTTP 与本地 Axum 服务器通信。 **设计:** Apple-glass 毛玻璃风格——磨砂半透明面板、`backdrop-filter: blur`、深色渐变背景上的鲜艳紫色点缀。在 macOS 上,使用 `vibrancy: "under-window"` 实现原生的毛玻璃效果。 **屏幕:** | 屏幕 | 内容 | |---|---| | **仪表板** | 全宽“测试提示”文本区 + 运行按钮;带有实时刷新的实时指标面板 | | **实时仪表板** | agent 认知循环活动的实时流视图 | | **Prometheus 指标** | 原始 Prometheus 指标端点输出(在仪表板下) | | **会话** | 带有状态徽章的会话列表;每会话事件时间线;一键导出 `.elc` 证书 | | **策略** | TOML 策略编辑器,带有实时语法验证;一键保存更改到服务器 | | **Tripwire** | 可配置的结构化规则:最小理由长度、要求 HTTPS、允许的路径/域、禁止的命令模式 | | **Tokens** | RBAC API token 管理 —— 创建、撤销和列出具有基于角色访问控制的 bearer token | | **Webhooks** | Webhook 端点配置 —— 添加、编辑和测试 SIEM 出站目标 | | **Observer** | 嵌入式 Observer 仪表板面板,用于实时事件监控 | | **测试** | 内置对抗性测试界面,用于验证护栏和扫描器防御 | | **DevHub** | 开发者参考面板,包含 API 文档、SDK 示例和集成指南 | | **设置向导** | 首次运行入门向导,用于 LLM 后端、数据库和护栏配置 | | **设置** | LLM 后端、模型选择和其他偏好设置 | GUI 解决了一个常见的运维痛点:Observer 仪表板嵌入在应用程序内,永远不会关闭或需要浏览器。
手动 GUI 命令(高级) ``` # 开发模式(热重载,需要后端运行) cd gui && npm install && npm run tauri dev # 生产 bundle cd gui && npm run tauri build # 安装程序位于:gui/src-tauri/target/release/bundle/ ```
构建生产 GUI 安装程序 Tauri 自动捆绑平台原生安装程序。确保已安装目标操作系统的前置条件,然后从 `gui/` 目录构建: ``` cd gui npm install npm run tauri build ``` **输出位置**(`gui/src-tauri/target/release/bundle/`): | 平台 | 安装程序格式 | 路径 | |----------|-----------------|------| | macOS | `.dmg` / `.app` | `bundle/dmg/EctoLedger__aarch64.dmg` | | Windows | `.msi` / `.nsis` | `bundle/msi/EctoLedger__x64_en-US.msi` | | Linux | `.deb` / `.AppImage` | `bundle/deb/ectoledger__amd64.deb` | **平台特定前置条件:** - **macOS:** Xcode Command Line Tools(`xcode-select --install`) - **Windows:** 带有 C++ 工作负载的 Visual Studio Build Tools,WebView2(Windows 10+ 预装) - **Linux:** `libwebkit2gtk-4.1-dev`、`libgtk-3-dev`、`libayatana-appindicator3-dev`(或旧发行版上的 `libappindicator3-dev`)、`librsvg2-dev` # Debian/Ubuntu 22.04+ sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev **代码签名(建议用于分发):** - macOS:设置 `APPLE_CERTIFICATE`、`APPLE_CERTIFICATE_PASSWORD` 和 `APPLE_SIGNING_IDENTITY` 环境变量,或在 `gui/src-tauri/tauri.conf.json` 的 `bundle > macOS` 下配置。 - Windows:在 `.msi` 输出上使用 `signtool.exe`,或通过 `TAURI_SIGNING_PRIVATE_KEY` 配置 Tauri 的内置签名。 对于 CI 驱动的构建,配置 `release.yml` GitHub Actions 工作流以在标签推送时自动化跨平台编译和产物上传。
## SDK ### Python SDK ``` # 仅核心客户端 pip install ectoledger-sdk # 包含 LangChain 支持 pip install 'ectoledger-sdk[langchain]' # 包含 AutoGen 支持 pip install 'ectoledger-sdk[autogen]' ``` ``` import asyncio from ectoledger_sdk import LedgerClient async def main(): async with LedgerClient("http://localhost:3000") as client: session = await client.create_session(goal="Audit Cargo.toml dependencies") await client.append_event(session.session_id, {"step": "read", "file": "Cargo.toml"}) ok = await client.verify_chain(session.session_id) print("Chain intact:", ok) await client.seal_session(session.session_id) asyncio.run(main()) ``` **LangChain 集成** - 将每个 agent 推理步骤追加到账本: ``` from ectoledger_sdk.langchain import LedgerTool ledger_tool = LedgerTool( session_id="", base_url="http://localhost:3000", ) agent_executor = AgentExecutor(agent=agent, tools=[search_tool, ledger_tool]) ``` **AutoGen 集成** - 在任何 `ConversableAgent` 上挂钩到回复处理: ``` from ectoledger_sdk.autogen import LedgerHook hook = LedgerHook(session_id="") hook.attach(my_conversable_agent) ``` 有关完整的 API 参考,请参阅 [`sdk/python/README.md`](sdk/python/README.md)。 ### TypeScript SDK ``` npm install ectoledger-sdk ``` ``` import { EctoLedgerClient } from "ectoledger-sdk"; const client = new EctoLedgerClient({ baseUrl: "http://localhost:3000" }); const session = await client.createSession("Summarise quarterly report"); await client.appendEvent(session.id, { step: "retrieved_docs", count: 42 }); const ok = await client.verifyChain(session.id); await client.sealSession(session.id); // Export audit certificate as a Blob const cert = await client.exportCertificate(session.id); ``` 零外部依赖 —— 使用原生 `fetch` API(Node 18+、浏览器、Deno、Bun)。使用 TypeScript 泛型完全类型化。非 2xx 响应抛出带有 `.status` 和 `.body` 属性的 `EctoLedgerApiError`。 有关完整的 API 参考,请参阅 [`sdk/typescript/README.md`](sdk/typescript/README.md)。 ## CLI 参考 ### `serve` - 启动 Observer 仪表板 ``` cargo run -- serve # Observer: http://localhost:3000(使用打印的 token 作为 ?token=… 或 Authorization header) ``` | 端点 | 描述 | |---|---| | `GET /` | Observer 仪表板(实时 SSE,内容已脱敏) | | `GET /metrics` | Prometheus 指标 | | `GET /api/metrics/security` | 安全事件 JSON(注入尝试、拒绝、中止、链失败) | | `GET /api/approvals/` | 待处理审批门状态 | | `POST /api/approvals/` | 提交审批决定 | ### `audit` - 运行 AI agent 审计 ``` # 基础审计 cargo run -- audit "Read server_config.txt" # 使用合规策略 cargo run -- audit "Audit Cargo.toml dependencies" \ --policy crates/host/policies/soc2-audit.toml # SQLite 后端 - 无需基础设施 DATABASE_URL=sqlite://ledger.db \ cargo run -- audit "Quick local audit" # 云凭证注入 AGENT_CLOUD_CREDS_FILE=~/.ectoledger/aws-audit.json \ cargo run -- audit "Audit S3 bucket policy for public exposure" \ --policy crates/host/policies/soc2-audit.toml # 交互式审批关卡 (stdin - 无需 dashboard) cargo run -- audit "Run nmap scan" --policy gate_policy.toml --interactive # 仅限开发 - 禁用 guard (需要显式确认标志) cargo run -- audit "Quick read" --no-guard --no-guard-confirmed ``` ### `report` - 导出会话报告 ``` # 支持的格式:json (默认), sarif, html, certificate (.elc), # github_actions, gitlab_codequality cargo run -- report --format sarif --output report.sarif cargo run -- report --format html --output report.html cargo run -- report --format certificate --output audit.elc cargo run -- report --format github_actions cargo run -- report --format gitlab_codequality --output codequality.json ``` 当任何发现具有 `high` 或 `critical` 严重性时,以代码 `1` 退出 —— 适合作为 CI 门禁。 ### `verify-session` - 验证 Ed25519 事件签名 ``` cargo run -- verify-session ``` ### `verify-certificate` - 离线证书验证 ``` cargo run -- verify-certificate audit.elc # 独立二进制文件(无需 Rust、PostgreSQL 或 Ollama - 发送给审计员) ./target/release/verify-cert audit.elc ``` ### `replay` - 重放会话 ``` cargo run -- replay cargo run -- replay --inject-observation "seq=3:injected content" ``` 对于调试和对抗性测试很有用。 ### `diff-audit` - 比较两个会话 ``` cargo run -- diff-audit \ --baseline \ --current \ [--output diff.json] ``` ### `orchestrate` - 多 agent 安全审计 运行三个顺序子 agent —— **Recon → Analysis → Verify** —— 每个都在独立的账本会话中。完成后,一个带有长度前缀 SHA-256 承诺的 `CrossLedgerSeal` 事件被追加到每个会话,在不合并其事件链的情况下将它们加密绑定在一起。 ``` cargo run -- orchestrate "Audit the Rust dependency tree for known vulnerabilities" cargo run -- orchestrate "Audit Nginx config" \ --policy shared_policy.toml --max-steps 25 # 通过环境变量进行特定角色策略覆盖: ECTO_RECON_POLICY=/etc/ectoledger/strict-recon.toml \ ECTO_VERIFY_POLICY=/etc/ectoledger/strict-verify.toml \ cargo run -- orchestrate "Audit production Kubernetes configuration" ``` **策略解析顺序(优先级从高到低):** 1. 角色特定环境变量(`ECTO_RECON_POLICY`、`ECTO_ANALYSIS_POLICY`、`ECTO_VERIFY_POLICY`) 2. 共享 `--policy` 文件(如果未设置角色特定变量,则适用于所有角色) 3. 内置硬编码默认值 | 子 agent | 允许的动作 | 备注 | |---|---|---| | **Recon** | `read_file`、`run_command` | `http_get` 被禁止 | | **Analysis** | `read_file` | 接收 Recon 观察作为目标上下文;生成发现 | | **Verify** | `read_file` | 在完成前独立确认每个 Analysis 发现 | ### `anchor-session` - Bitcoin 或 EVM 时间戳 ``` # 通过 OpenTimestamps 的 Bitcoin (默认) cargo run -- anchor-session # EVM 链 (Ethereum, Polygon, 或任何兼容 EVM 的网络) EVM_RPC_URL=https://mainnet.infura.io/v3/ \ EVM_CHAIN_ID=1 \ EVM_CONTRACT_ADDRESS=0x... \ EVM_PRIVATE_KEY=0x... \ cargo run -- anchor-session --chain ethereum ``` 将账本尖端哈希提交给 OTS 聚合器池(Bitcoin 路径)或在已部署的 `EctoLedgerAnchor` 智能合约上调用 `anchor(bytes32)`(EVM 路径)。在这两种情况下,都会将一个 `Anchor` 事件追加到会话中,嵌入证明和交易哈希以供独立验证。 EVM 锚定在所有预构建二进制文件中默认启用(`evm` 功能已开启)。不需要 `--features evm` 标志。 ### `red-team` - 对抗性防御测试 ``` cargo run -- red-team --target-session cargo run -- red-team --target-session \ --attack-budget 100 --output red-team-report.json ``` 通过 LLM 生成注入 payload,并在隔离环境中针对输出扫描器和 tripwire 测试每个 payload。退出代码 `1` 表示有任何 payload 通过了所有检查 —— 可直接集成到 CI 中。对于单 payload 手动测试,请改用 `replay --inject-observation`。 ### `prove-audit` - SP1 零知识证明 ``` cargo build --features zk cargo run --features zk -- prove-audit cargo run --features zk -- prove-audit \ --policy crates/host/policies/soc2-audit.toml --output audit.elc ``` 在完整的事件哈希链和策略承诺上生成 SP1 ZK 有效性证明。验证者可以在无法访问原始事件 payload 的情况下确认策略合规性 —— 这是受监管行业(医疗保健、金融)的正确工具,在这些行业中,被审计数据不能离开客户的边界。对于所有其他用例,标准 `.elc` 证书(五重验证)提供了足够的加密来源,而没有证明生成的开销。 ## 审计证书(`.elc`) 每个完成的会话都可以导出为一个自包含的 `.elc` 文件,该文件可针对五个独立的保证完全离线验证: | 支柱 | 保证 | |---|---| | **Ed25519 签名** | 防篡改——整个 payload 使用会话密钥对签名;公钥嵌入在证书中;无需受信任的第三方 | | **SHA-256 哈希链** | 间隙和变异检测——无需重放执行即可检测链中任何位置的任何插入、删除或修改 | | **Merkle 包含证明** | 高效的发现抽查——每个发现都带有一个兄弟哈希路径,指向基于所有事件 `content_hash` 值构建的 Merkle 根;O(log n) 验证 | | **OpenTimestamps / Bitcoin 锚** | 时间上的不可否认性——证明审计在区块 N 之前完成,任何人都可以验证而无需信任发行者 | | **目标哈希完整性** | 会话完整性——`sha256(goal)` 在创建时存储;在每个事件上重新验证;agent 目标不能在会话中途重定向 | 构建时使用 `--features zk` 时,可以使用第六个证明(SP1 ZK 有效性证明)。 `verify-cert` 二进制文件是一个静态的、无依赖的二进制文件(< 5 MB),设计用于交付给客户、审计员或监管机构。它不需要 Rust 工具链、PostgreSQL 或 Ollama。 ## 去中心化身份与 W3C 可验证凭证 会话和 `.elc` 证书带有一个可选的 `session_did` 字段。如果存在,它包含一个从会话 Ed25519 密钥对派生的 `did:key:` URI —— 为每个审计会话提供一个 W3C 兼容的、自主权的身份锚,任何符合标准的 DID 解析器都可以验证,而无需回调 EctoLedger 实例。 ### 可验证凭证颁发 当 agent 会话完成时,EctoLedger 会自动颁发一个 W3C VC-JWT,以防篡改、可移植的凭证形式编码会话身份、目标、策略哈希和完成状态: ``` { "iss": "did:key:z...", "sub": "did:key:z...", "jti": "urn:uuid:", "iat": 1740000000, "exp": 1747776000, "vc": { "@context": ["https://www.w3.org/2018/credentials/v1", "https://ectoledger.security/2026/credentials/v1"], "type": ["VerifiableCredential", "EctoLedgerSessionCredential"], "credentialSubject": { "id": "did:key:z...", "sessionId": "", "goal": "Audit S3 bucket policies", "policyHash": "sha256:", "status": "completed", "issuedAt": "2026-02-22T03:00:00Z" } } } ``` ### REST 端点 | 端点 | 方法 | 描述 | |---|---|---| | `/api/sessions/{id}/vc` | `GET` | 检索已完成会话的 VC-JWT 和解码后的 payload | | `/api/sessions/{id}/vc/verify` | `GET` | 解析并验证 VC-JWT(结构完整性 + 有效期限检查) | **检索会话凭证:** ``` curl -H "Authorization: Bearer $OBSERVER_TOKEN" \ http://localhost:3000/api/sessions//vc | jq . ``` **验证(解析)会话凭证:** ``` curl -H "Authorization: Bearer $OBSERVER_TOKEN" \ http://localhost:3000/api/sessions//vc/verify | jq . # → { "valid": true, "vc_payload": { ... } } ``` 验证端点执行: 1. **结构验证** - 检查 JWT 是否具有所需的 `header.payload.signature` 格式。 2. **有效期检查** - 拒绝 `exp` 声明已过期的凭证(默认生命周期:90 天)。 3. **签名验证** - **此 REST 端点不执行**;要获得完整的 Ed25519 签名验证,请使用 `crates/host/src/verifiable_credential.rs` 中的 `verify_vc_jwt` Rust API。 ### 编程验证 ``` use ectoledger::verifiable_credential::{build_vc_jwt, verify_vc_jwt, VcVerifyError}; // Verify a VC-JWT with the session signing key let vk = signing_key.verifying_key(); match verify_vc_jwt(&vc_jwt, Some(&vk)) { Ok(payload) => println!("Valid credential: {}", payload), Err(VcVerifyError::Expired) => eprintln!("Credential has expired"), Err(VcVerifyError::InvalidSignature) => eprintln!("Signature mismatch"), Err(e) => eprintln!("Verification error: {}", e), } ``` ## Webhooks 和 SIEM 集成 EctoLedger 向任何 HTTP 端点发出结构化事件 —— 配置一次即可接收所有安全相关 agent 决策的实时通知。 **事件类型:** | 类型 | 触发条件 | |---|---| | `Observation` | Agent 生成被标记或中止的观察 | | `GuardDenial` | 护栏进程对提议的意图返回 `DENY` | | `TripwireRejection` | Tripwire 拒绝一个动作(路径逃逸、被阻止的、危险命令、缺失理由) | **配置:** ``` WEBHOOK_URL=https://siem.corp.example/ingest WEBHOOK_BEARER_TOKEN= SIEM_FORMAT=json # json (default) | cef | leef WEBHOOK_INCLUDE_GUARD=true # default true - include GuardDenial events WEBHOOK_INCLUDE_TRIPWIRE=true # default true - include TripwireRejection events ``` CEF 和 LEEF payload 包含 `event_kind`、`session_id`、`payload_hash` 和时间戳。这些格式可直接被 Splunk、IBM QRadar 和 ArcSight 摄取。 ## 策略系统 ### 行业策略包 | 文件 | 标准 | 重点 | |---|---|---| | `crates/host/policies/soc2-audit.toml` | SOC 2 Type II | 访问管理、日志记录、静态加密 | | `crates/host/policies/pci-dss-audit.toml` | PCI-DSS v4.0 | 持卡人数据范围、网络分段 | | `crates/host/policies/owasp-top10.toml` | OWASP Top 10 2021 | 注入、身份验证失败、加密失败、SSRF、配置错误 | | `crates/host/policies/iso42001.toml` | ISO 42001:2023 | AI 管理系统 —— 7 个条款中的 14 项控制 | ``` cargo run -- audit "Audit SOC2 controls" \ --policy crates/host/policies/soc2-audit.toml cargo run -- audit "Audit cardholder data environment" \ --policy crates/host/policies/pci-dss-audit.toml cargo run -- audit "Audit web application for OWASP Top 10" \ --policy crates/host/policies/owasp-top10.toml cargo run -- audit "ISO 42001 AI system audit" \ --policy crates/host/policies/iso42001.toml ``` ### 策略 DSL TOML 策略文件支持四种规则类别。所有部分都是可选的。 ``` name = "example-policy" max_steps = 30 # 1. 允许/禁止操作列表 [[allowed_actions]] action = "read_file" [[forbidden_actions]] action = "http_get" # 2. 条件命令规则 - 按顺序评估;优先匹配 [[command_rules]] program = "curl" arg_pattern = "^https://(internal\\.corp|api\\.example)\\.com" decision = "allow" [[command_rules]] program = "curl" arg_pattern = ".*" decision = "deny" reason = "curl permitted only to approved internal domains" # 3. 观察内容规则 - 每次执行后应用 [[observation_rules]] pattern = "(?i)(password|secret|api.key)\\s*[:=]\\s*\\S+" action = "redact" # redact | flag | abort label = "credential_leak" # 4. 审批关卡触发器 - 策略驱动的人机交互 [[approval_gates]] trigger = "action == 'run_command' && command_contains('nmap')" require_approval = true timeout_seconds = 300 on_timeout = "deny" ``` **规则类型:** - **`command_rules`** - 仅应用于 `run_command` 动作。`program` 匹配第一个 token;`arg_pattern` 是剩余参数的正则表达式。决策:`allow`、`deny`、`require_approval`。 - **`observation_rules`** - 在每次工具执行后应用于原始观察文本。`redact` 将匹配项替换为 `[REDACTED:
标签:AI代理, AI安全, AutoGen, Chat Copilot, Ed25519签名, ISO 42001, LangChain, Lerna, Rust, W3C可验证凭证, Zenmap, 不可抵赖性, 人工智能安全, 去中心化身份, 可视化界面, 可验证执行, 合规性, 哈希链, 审计追踪, 密码学, 手动系统调用, 数据完整性, 比特币锚定, 治理, 测试用例, 策略执行, 网络流量审计, 请求拦截, 轻量级, 逆向工具, 通知系统, 防篡改, 零知识证明, 风险控制, 黑盒记录仪