Gateway Live podd Proxy Engine and Zero-Trust Egress Sidecar Daemon
此内容尚不支持你的语言。
Source:
docs/enhancements/0009-gateway-egress-sidecar/README.md· Status:implemented· Area:core· Milestone:—| Field | Value | | :--- | :--- | | CEP Number |0009| | Title | Gateway LivepoddProxy Engine and Zero-Trust Egress Sidecar Daemon | | Authors |@cubeplex-arch| | Status |implemented| | Target Version |v0.2.0| | Created |2026-11-10| | Last Updated |2026-11-10|
Summary
Section titled “Summary”This CEP completes the end-to-end data plane and zero-trust egress plane across pkg/gateway, pkg/egress, and a new cmd/cubepod-egress binary:
pkg/gatewayadds upstreampoddHTTP forwarding (RegisterPoddURL(sandboxID, poddURL)): whenever a sandbox has a livepoddURL registered,POST /commands/run,GET /commands/{id}/logs,POST /commands/{id}/kill,PUT /files,GET /files, andPOST /files/archive-syncare proxied directly to the sandbox’spodddaemon (:49983).pkg/gatewayandpkg/egressexpose the mTLS secret exchange HTTP handler (POST /internal/v1/egress/exchange) and secret binding registration duringPOST /sandboxes.pkg/egress/proxy.goandcmd/cubepod-egress/main.goimplement the Zero-Trust Egress Proxy sidecar that intercepts outbound requests from the sandbox, enforcesAllowedHosts/DeniedHostspolicy, scans headers forcpodref_<32-char-base32>tokens, exchanges them over mTLS against the Gateway Vault, and injects the real API key on the wire to the upstream destination.
Motivation
Section titled “Motivation”In v0.1.0, pkg/egress provided the cryptographic CA, policy matcher, and Vault struct, while pkg/gateway executed commands locally. Connecting pkg/gateway to live podd instances and providing the runnable cubepod-egress HTTP forward/reverse proxy completes the entire security and execution loop.
- Live
poddData-Plane Forwarding inpkg/gateway:- Add
SetPoddURL(sandboxID, poddURL string)(and automaticpoddrouting whenrec.PoddURL != ""). - Forward
/commands/run,/commands/{cmdID}/logs,/commands/{cmdID}/kill,/files, and/files/archive-synctorec.PoddURL(/v1/commands/...,/v1/files...) whenrec.PoddURL != "", while retaining the local fallback whenrec.PoddURL == "". - Call
POST <PoddURL>/v1/lifecycle/prepare-stopduringPOST /sandboxes/{sandboxID}/pausewhenrec.PoddURL != "".
- Add
- Zero-Trust Egress Exchange & Sidecar (
pkg/egress/proxy.go&cmd/cubepod-egress/main.go):- Implement
VaultExchangeHandler(vault *Vault, ca *CA) http.HandlerFuncforPOST /internal/v1/egress/exchangethat extractssandboxIDfrom the mTLS peer certificateCommonName(orX-CubePod-Sandbox-IDwhen running over local loopback trust in tests), validates(sandboxID, placeholder, sniHost, headerName)viavault.Exchange(...), and returns{"secret": "<real-value>"}or403 Forbidden. - Implement
EgressProxy(pkg/egress/proxy.go) andcmd/cubepod-egress/main.go:- Checks destination host against
AllowedHostsandDeniedHosts(403 Forbiddenif blocked). - Scans outbound HTTP request headers for
cpodref_tokens (e.g.Authorization: Bearer cpodref_...orX-Api-Key: cpodref_...), calls the Exchange endpoint over mTLS (ca.ClientTLSConfig), replaces thecpodref_substring with the real secret in flight, and forwards the request to the upstream target without ever logging or persisting the secret.
- Checks destination host against
- Implement
Non-Goals
Section titled “Non-Goals”- Kernel-level eBPF packet filtering (handled at the Pod
iptables/NetworkPolicylayer).
Proposal
Section titled “Proposal”Risks and Mitigations
Section titled “Risks and Mitigations”| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Exfiltration via header reflection echo service | High | Low | vault.Exchange strictly verifies both sniHost and headerName against the SecretBinding allowlist before releasing the secret. |
Design Details
Section titled “Design Details”Wire Protocol for /internal/v1/egress/exchange
Section titled “Wire Protocol for /internal/v1/egress/exchange”- Request:
When served over mTLS ({"sandboxID": "cpod-123","placeholder": "cpodref_ABCDEFGHIJKLMNOPQRSTUVWXYZ234567","sniHost": "api.openai.com","headerName": "Authorization"}
r.TLS != nil && len(r.TLS.PeerCertificates) > 0),sandboxIDis cryptographically enforced fromr.TLS.PeerCertificates[0].Subject.CommonName. - Response (
200 OK):{"secret": "sk-proj-real-openai-key"}
Test Plan
Section titled “Test Plan”- Unit & Integration Tests:
pkg/egress/proxy_test.go:- Start a mock upstream LLM server (
httptest.NewServer) that assertsAuthorization: Bearer sk-real-secret-999. - Start a real mTLS Vault Exchange server using
CAandVault(httptest.NewUnstartedServerwithca.ServerTLSConfig()). - Start
EgressProxyconfigured with the sandbox’s mTLS client cert (ca.MintSandboxCert("sbx-1")). - Send an HTTP request through
EgressProxycarryingAuthorization: Bearer cpodref_<token>. - Verify the upstream server receives
Authorization: Bearer sk-real-secret-999, while a request to an unauthorized host (evil.com) or wrong header (X-Leak) is rejected with403 Forbidden!
- Start a mock upstream LLM server (
pkg/gateway/server_test.go:- Verify
Serverwith a mock/livepoddHTTP server (SetPoddURL) forwards/commands/run,/logs,/kill,/files,/files/archive-sync, and/v1/lifecycle/prepare-stopon/pause.
- Verify
Graduation Criteria
Section titled “Graduation Criteria”go test -v -race ./pkg/egress/... ./pkg/gateway/...andgo build ./cmd/cubepod-egresspass with 0 errors.
Upgrade / Downgrade Strategy
Section titled “Upgrade / Downgrade Strategy”- Fully backward-compatible with
v0.1.0Gateway tests.
Production Readiness Review (PRR)
Section titled “Production Readiness Review (PRR)”- Security: Real secrets never touch disk or logs; mTLS client certificate
CommonNamebinds every exchange request to its originating sandbox.
Alternatives Considered
Section titled “Alternatives Considered”- Passing secrets via environment variables at container start: Explicitly forbidden by CubePod Security Invariant #3.