epic: Cortex as the egress proxy for MOCA's sandbox service (SBX)

未关闭
#1,490 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
25/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
go

调研方向

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 内容生成。

描述

enhancement Identity

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 Host that differs from the CONNECT authority gets 421 (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() behind include_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

主要语言
Go
星标
23
派生
44
平均合并
14 小时 38 分钟
30 天内合并 PR
254

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

rossoctl/cortex 的其他 Issue

查看 rossoctl/cortex 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。