epic: Cortex as the egress proxy for MOCA's sandbox service (SBX)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 25/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- go
- 领域
- backend, networking, security
调研方向
Start with the linked MOCA MI1 §8 contract and §12.3 conformance suite, then review the listed Cortex entry point core/listener/forwardproxy/server.go:963-989 and plugin registration in core/plugins/README.md:60. First settle deployment shape A or B in a design session; the child issues and their named conformance cases define the implementation path. Done means Cortex passes MOCA's conformance suite and verifies the sandbox grant.
由索引模型根据 Issue 内容生成。
描述
Goal
Make Cortex the egress proxy for MOCA's sandbox service (SBX): the one place where traffic from code running inside a sandbox leaves for the internet, where each user's real credentials are swapped in, and where Cortex's policy plugins (IBAC, SPARC, OPA, budgets, observability) run on that traffic.
This epic replaces #905. That issue's history (the Z5 per-subject injector, two rescopes, a gap analysis) is summarised here, so the design sessions can start from this page.
Where Cortex would sit
SBX runs every tool call in a fresh Firecracker microVM (ADR-0042, SBX0 design). The VMs have no network device. A guest's HTTPS_PROXY=http://127.0.0.1:3128 is spliced over vsock to a Unix socket per VM on the KVM host. One egress proxy per host is shared by every VM on it, so it serves many users at once.
guest (curl, pip, git, SDKs) KVM host internet
HTTPS_PROXY ─► vsock 1025 ─► per-VM Unix socket ─► egress proxy ─► allow list, SSRF ─► github.com …
(fd handed over by │ identity = the socket the
vmpool, SCM_RIGHTS) │ connection arrived on
└► (identity, host) → user's credential
Each guest holds only an inert placeholder (moca-placeholder). The proxy overwrites it with the right user's credential for the destination host.
The contract is MOCA MI1 §8, and its black-box test suite is §12.3.
The plan, and why Cortex is not on the critical path
MOCA ships its own small Go proxy, moca-egress, first (rossoctl/moca#583: transport slice, the control protocol, and a public conformance suite at remote-worker/egress/conformance). Cortex replaces it when it passes the same suite and MOCA needs a capability only Cortex has. Each child issue names the conformance case that proves it is done.
Not yet decided: two deployment shapes. These change how much each issue has to cover. Please settle them in the first design session:
- A. Cortex owns everything. Cortex accepts the per-VM sockets and does identity, the allow list and SSRF checks itself. Every issue below applies.
- B. MOCA front end, Cortex behind it. A small MOCA component owns the VM sockets, the connection → sandbox binding, the allow list and the SSRF check. It stamps a verified identity onto the plaintext CONNECT. Cortex trusts that identity only on the front end's socket. #1477, #1483 and #1484 move to MOCA, and #1476 shrinks.
Child issues
Priorities: P0 means no per-user injection without it. P1 means needed before any user. P2 means needed before many users. P3 is compatibility.
| Issue | Pri | Gap | In #905's breakdown? |
|---|---|---|---|
| #1476 | P0 | Caller identity from the connection, carried into every bridged request and every plugin | step 4 |
| #1477 | P0 | Per-VM Unix-socket listeners handed over at run time (SCM_RIGHTS), with a control channel | step 3 (Unix sockets only) |
| #1478 | P0 | Credential keyed by (identity, host), resolved from MOCA's token endpoint | step 1 |
| #1479 | P0 | Inject into the header the credential declares (Bearer, Basic for git, x-api-key), always overwriting | new |
| #1480 | P1 | Fail closed on hosts that have a credential: never fall back to an opaque tunnel | new |
| #1481 | P1 | Refuse to send a credential over plain HTTP (403 plaintext_credential) |
new |
| #1482 | P1 | Exactly one audit event per injection, in MOCA's audit shape | step 2 |
| #1483 | P1 | Deny-by-default destination allow list | new |
| #1484 | P1 | SSRF guard: resolve once, refuse private and metadata ranges, dial the checked address | new |
| #1485 | P2 | Per-VM connection cap and per-session request cap (429) |
new |
| #1486 | P2 | Session recording and the session API on a shared host | new |
| #1487 | P3 | Run body-reading plugins (IBAC, SPARC, tool-prune) under a streaming contract | new |
| #1488 | P3 | WebSocket upgrades on intercepted connections | new |
| #1489 | — | Verify MOCA's sandbox grant and pass the conformance suite | step 5 |
Suggested order: settle the A/B decision first. Then #1476 → #1478 → #1479, the injection path, which only becomes safe once #1476 lands. Then #1480, #1481 and #1482. #1483–#1488 depend on the A/B decision, and #1489 is the final gate.
Already matching
Nothing needs doing here:
- An inner
Hostthat differs from the CONNECT authority gets421(core/listener/forwardproxy/server.go:963-989). - The upstream certificate is verified before a leaf is minted.
- The plugin model fits. Plugins register in
init()behindinclude_plugin_<name>build tags (core/plugins/README.md:60), so MOCA can link its own identity or resolver plugins into a downstream build without forking.
References
- MOCA: MI1 §8 + §12.3, P4.1 egress transport,
proto/egress/v1/control.proto, the MOCA-side stub rossoctl/moca#241. - Cortex evidence: the code was read at
maind4394da(2026-10-22). It was read, not built or run against MOCA's contract. - Supersedes #905. Parent: rossoctl/rossoctl#2546 (Stream 1).
- 主要语言
- Go
- 星标
- 23
- 派生
- 44
- 平均合并
- 14 小时 38 分钟
- 30 天内合并 PR
- 254
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
rossoctl/cortex 的其他 Issue
-
feature: let `session.archive` set where it writes, so a second Cortex can keep its own sessions未关闭enhancement
难度 4/5 3-5 天 新手友好度 54/100
维护者通常 1 天内回复
-
feature: agentop observe — show a request and its response as one row可能已有人在做 @huang195 今天认领。 未关闭enhancement ux
rossoctl/cortex#1681 · 已指派 1 人 ·
维护者通常 1 天内回复
-
feature: agentop observe — search user prompts and agent responses across a session's events可能已有人在做 @huang195 今天认领。 未关闭enhancement ux
rossoctl/cortex#1680 · 已指派 1 人 ·
维护者通常 1 天内回复
-
feedback laptop
难度 5/5 一周以上 新手友好度 28/100
维护者通常 1 天内回复
-
chore: Remove the decline_responses_websockets translation after a deprecation release可能已有人在做 @Alan-Cha 于 4 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 55/100
rossoctl/cortex#1625 · 已指派 1 人 ·
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
-
难度 2/5 1-3 小时 新手友好度 78/100
router-for-me/CLIProxyAPI#7330 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
bug os:ios
难度 2/5 1-3 小时 新手友好度 72/100
hajimehoshi/ebiten#4039 · 2 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 65/100
维护者通常 9 天内回复