Skip to content

feat(interactive): M5 trusted Host provenance and model data isolation - #6

Merged
rockyshi1993 merged 24 commits into
mainfrom
feat/interactive-m5-trusted-host
Nov 10, 2026
Merged

rockyshi1993 merged 24 commits into
mainfrom
feat/interactive-m5-trusted-host

Conversation

@rockyshi1993

@rockyshi1993 rockyshi1993 commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Scope — approved P0-A M5 only

Build a separate Host-only security facade around the completed M4 Coordinator without changing the existing Standard root API or implementing any P0-B features.

  • Host-signed Ed25519 attestation for Agent result/failure receipts; signature covers canonical result bytes, namespace, run/request/node/attempt, Program artifact hash, policy hash, proof ID and bounded issuance/expiry window. Verifier rejects before any CAS, with non-disclosing error.
  • Strict Agent receipt schema rejects Human, Action, Verification, caller-selected transition IDs and model-supplied provenance strings.
  • Trusted Program allowlist validated before importing compiler-produced JS, since a digest alone is not compiler authenticity.
  • Host-only getPublicAgentTask reads the authoritative waiting checkpoint, enforces an explicit allowlist of Agent input fields and requires affirmative Host disclosure authorization before releasing a model task. Never includes private State, Host policy, receipt ledger, DB/credential references.
  • Policy pins public key fingerprints, trusted artifact hashes, disclosure policy, input allowlist and proof validity bounds, so unsupervised trust-root drift blocks an in-progress run.
  • Cryptographic verification and signing byte helpers are public/pure, but no private signing key or signing endpoint is exposed by FlowKit.
  • Added real Linux cross-UID process check (Node 22 + Node 24) showing a low-privileged model process can read a public task but gets access-denied on Host private key and SQLite files. On Windows, the host must configure and independently validate corresponding ACL isolation.
  • Package manifest, TS contracts, installed-package signed Agent smoke test, attack-negative suite, and Host-only integration/security documentation.

Security boundary explicitly NOT claimed

The low-level M4 createInteractiveCoordinator remains an internal Host capability. This facade is not an in-process sandbox; any model that shares Host UID, private key, database writes, raw Coordinator access or a trusted signer may bypass it. Those environments must be BLOCKED for trusted-host operations. The test signer uses isolated test keys; real Codex/Claude/Grok native approval and transport origin proof remain out of scope and must not be invented.

Gate

Review actual diff and semantics; run real npm run verify and documentation consumers on Ubuntu/Windows × Node22/24; run separate real Linux OS-user isolation jobs on Node22+24. Repair every observed P0/P1, rerun all relevant CI at the exact final HEAD before squash merging. Do not publish npm, deploy, open source, or progress beyond P0-A/M5 before accepting this gate.


Note

High Risk
Changes security-critical Host/model boundaries, cryptographic receipt verification, and disclosure policy; incorrect handling could allow forged receipts or unintended data leakage to models.

Overview
Adds createTrustedInteractiveHost, an M5 security facade around the existing Coordinator that keeps complete() and the store Host-private while exposing only getPublicAgentTask and accept({receipt, attestation}) to the model boundary.

Signed Agent receipts use canonical Ed25519 attestations (host-attestation.mjs): pinned program artifacts, public keys, input allowlists, disclosure approval, and proof lifetime checks run before any CAS; Human/Action/Verification and string provenance are rejected.

Shipping & evidence: new exports/types, package manifest entries, interactive-host-security.md, consumer and attack-negative tests, and a dedicated CI job running tests/security/host-isolation.mjs (unprivileged nobody process cannot read Host key/SQLite).

Reviewed by Cursor Bugbot for commit 1ae2dfa. Bugbot is set up for automated code reviews on this repo. Configure here.

…nance, artifact allowlist and public task disclosure gates
…ifact allowlist, policy and adversarial provenance

Copy link
Copy Markdown
Contributor Author

FlowKit P0-A / M5 — 完整源码复审与验收记录(2026-11-10 UTC)

审查版本(不可替换):1ae2dfa998f4e0d679aff27ec4245728690c80e1;基线 4658381e75bd5e420b53dacfd80aea1193d144b4。本 PR 仅覆盖 M5 可信 Host 安全边界,不含 M6 或 P0-B。

源码 / 契约独立核对

  1. 原 Standard 6 个根 SDK 函数保持不变;./interactive 仍为独立子路径,M5 仅新增 Host 公钥验证、纯签名消息编码、可信 Host facade。打包白名单和 TypeScript 包消费测试同步更新。
  2. 可信 JS Program:仅允许 Host 显式批准的 artifactHash,在导入 Program 之前拒绝未知哈希;哈希只证明内容身份,不冒充编译器来源认证。运行仍由 M4 冻结 programTable 驱动。
  3. 可信 Host 回执:只接受 Agent result/failure,Ed25519 公钥校验严格绑定 domain、namespace、runId、requestId、nodeId、attempt、artifactHash、policyHash、canonical result digest、proofId 和时间范围。所有不一致/伪造/过期的新回执在任何 CAS 前拒绝;错误不回显密钥或敏感结果。
  4. 持久化重放:已成功接纳的相同回执允许在有效签名验证后重取既有 Ack,即使证明本身过期;不能用旧签名引入新回执。M4 仍执行同内容幂等、不同内容冲突和原 acceptedRevision。
  5. 最小披露:模型任务取自权威 Checkpoint,而非外部入参;仅暴露明示字段,当前输入与 missing 字段名称均需逐项白名单批准。异步 DLP 审批完成后再次核对 revision/requestId,拒发过期 Pending;审批异常一律脱敏拒绝。
  6. 隔离与不越权:模型不获取 Store、Host 私钥、完整 State 或 raw Coordinator;未启用 Human/Action/Verification/Loop/Parallel;模型写的字符串 provenanceRef 不具有审批权。文档明确:同 UID/同文件权限/可写 Host 数据库时不能宣称安全,须先实现 OS 权限隔离。

审查发现及关闭

  • 发现异步披露审批期间 Pending 可被其他 Host 推进:完成后重读 CAS revision/requestId,并补攻击反例。
  • 发现未命中的 missing 字段名称可能泄露:纳入显式白名单,补拒绝测试。
  • 发现短期签名过期与长期幂等 Ack 需求冲突:只对已接纳且内容完全一致、签名仍可验证的回执保留历史 Ack;对新回执始终要求新鲜签名。
  • 发现负例只篡改未重新签名不能充分证明身份绑定:增加真实私钥签署但身份/程序/策略/请求/结果不匹配的对抗用例。
  • 私有 DLP 回调异常可能包含敏感内容:统一映射非泄露错误。
    以上修订均在最新完整 CI 中重验,当前 M5 范围没有已知未关闭的 P0/P1。

实际、可追溯的门禁证据

GitHub Actions 42837615421 @ EXACT 1ae2dfa,7/7 jobs COMPLETED/SUCCESS。

  • Ubuntu 24.04 × Node 22.13.0 — npm run verify、文档消费成功;333 tests / 333 PASS / 0 FAIL / 0 SKIP。
  • Ubuntu 24.04 × Node 24.22.1 — 同上。
  • Windows 2025 × Node 22.13.0 — 同上。
  • Windows 2025 × Node 24.22.1 — 同上。
  • Linux Host OS-user isolation × Node22、Node24:分别真实启动低权限 nobody Node 进程;公开 Agent Task 可读,Host 私钥与 SQLite 读写均拒绝。
  • Website job:成功。

剩余明确边界

本 PR 不是 in-process JS sandbox,不能证明 Windows 宿主 ACL、Codex/Claude/Grok 原生审批来源、任何真实第三方 Agent Provider 的可信会话记录或外部 exactly-once。M6 才做最终宿主集成验收。V0.6-R5 正文未在本轮以完整文件形式取得;本复审依据已经确认的 P0-A 约束、实际 M1–M4 产物/源码差异、审查反例及真实 CI,不伪称对不可访问设计文档逐行复核。未执行 npm 发布、站点部署、开源或 P0-B/P1/P2 变更。

M5 复审裁决:通过 scoped 代码与 CI 门禁,允许按已授权的 squash merge 进入 main;后续 M6 单独验收。

@rockyshi1993
rockyshi1993 marked this pull request as ready for review November 10, 2026 14:51
@rockyshi1993
rockyshi1993 merged commit c873e3e into main Nov 10, 2026
10 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1ae2dfa. Configure here.

throw new TypeError('Invalid Host binding identifier');
}
return value;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Key ID length limits disagree

Medium Severity

trustedPublicKeys ids pass name() up to 128 characters and are pinned into policyHash, but createAgentReceiptStatement and encodeAgentReceiptStatement reject a keyId longer than 64. A Host that uses a long id, including a sha256: fingerprint, can start runs that no valid proof can ever complete.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1ae2dfa. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant