epic: Cortex as the egress proxy for MOCA's sandbox service (SBX)
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- go
- Lĩnh vực
- backend, networking, security
Hướng nghiên cứu
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.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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).
- Ngôn ngữ chính
- Go
- Star
- 23
- Fork
- 44
- Merge trung bình
- 14 giờ 38 phút
- Pull request đã merge (30 ngày)
- 254
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của rossoctl/cortex
-
feature: let `session.archive` set where it writes, so a second Cortex can keep its own sessionsĐang mởenhancement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 54/100
Maintainer thường phản hồi trong vòng 1 ngày
-
feature: agentop observe — show a request and its response as one rowCó thể đã có người làm @huang195 đã nhận hôm nay. Đang mởenhancement ux
rossoctl/cortex#1681 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
feature: agentop observe — search user prompts and agent responses across a session's eventsCó thể đã có người làm @huang195 đã nhận hôm nay. Đang mởenhancement ux
rossoctl/cortex#1680 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
feedback laptop
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 28/100
Maintainer thường phản hồi trong vòng 1 ngày
-
chore: Remove the decline_responses_websockets translation after a deprecation releaseCó thể đã có người làm @Alan-Cha đã nhận 4 ngày trước. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 55/100
rossoctl/cortex#1625 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của rossoctl/cortex
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
router-for-me/CLIProxyAPI#7330 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug os:ios
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
hajimehoshi/ebiten#4039 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 9 ngày