proxy

package
v0.0.0-...-4048c46 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2026 License: AGPL-3.0 Imports: 40 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// EgressRuleBlockedAddress denies a destination that resolves to an
	// address the engine never forwards to, whatever the policy says. It is
	// what keeps the proxy from becoming a new way to reach the daemon's own
	// loopback services or a cloud metadata endpoint.
	EgressRuleBlockedAddress = "engine.blocked-address"
	// EgressRulePolicyUnavailable denies when the sandbox's policy cannot be
	// read. An unreadable declaration is not an absent one, so the proxy denies
	// rather than forwarding on a policy it could not evaluate.
	EgressRulePolicyUnavailable = "engine.policy-unavailable"
	// EgressRuleUnresolvedAddress denies when the destination does not resolve.
	EgressRuleUnresolvedAddress = "engine.unresolved-address"
	// EgressRuleBlockedPort denies a control-plane port the engine never
	// forwards to, whatever the policy says. A sandbox that could reach a
	// cluster's etcd or kubelet through the proxy would have a path to the
	// credentials and the workloads of the platform hosting it, so the
	// declaration cannot buy that path back.
	EgressRuleBlockedPort = "engine.blocked-port"
	// EgressRuleCredentialUnavailable denies an allowed L7 request whose
	// injected credential could not be resolved from the daemon environment.
	EgressRuleCredentialUnavailable = "engine.credential-unavailable"
	// EgressRuleL7Unavailable denies an HTTPS allowance that declares methods or
	// paths when the proxy cannot inspect the request. A declaration that asked
	// for L7 enforcement is not silently downgraded to a destination-only
	// allowance: either the deployment opts into TLS interception (and the guest
	// trusts the CA) or the connection is refused.
	EgressRuleL7Unavailable = "engine.l7-inspection-unavailable"
)

Engine-owned rule IDs. They are stable so a decision record names the rule that produced it, and a deny reason never depends on a project's wording.

View Source
const DefaultEgressDialTimeout = 30 * time.Second

DefaultEgressDialTimeout bounds how long the proxy waits for an upstream connection it opened for a sandbox.

View Source
const RuntimeLLMFacadePrefix = "/api/runtime/sandboxes/"

Variables

This section is empty.

Functions

func BridgeRuntimeLLMStreamResponse

func BridgeRuntimeLLMStreamResponse(c echo.Context, resp *http.Response, req runtimeLLMStreamBridgeRequest) error

func EgressDispatchHandler

func EgressDispatchHandler(daemon http.Handler, egress http.Handler) http.Handler

EgressDispatchHandler routes a guest's forward-proxy traffic to the egress proxy and everything else to the daemon's own handler, so the proxy is served on the listener a sandbox can already reach instead of a second port a deployment would have to publish.

A request is treated as proxy traffic when it names an absolute target (the form only a proxy client produces) or when it is a CONNECT carrying a proxy credential. A CONNECT without one is left to the daemon: the daemon's own HTTP/2 clients may use the method, and the proxy answers an unauthenticated CONNECT with 407, which would turn that client's request into an authentication error. The credential is therefore what marks the request as the proxy's, and the proxy is the only producer of it.

func IsHTTPRequestBodyTooLarge

func IsHTTPRequestBodyTooLarge(err error) bool

func IsRuntimeLLMFacadeRequest

func IsRuntimeLLMFacadeRequest(r *http.Request) bool

func JupyterTargetReachable

func JupyterTargetReachable(proxyState domain.ProxyState, timeout time.Duration) bool

func NewRuntimeLLMHTTPClient

func NewRuntimeLLMHTTPClient(responseHeaderTimeout time.Duration) *http.Client

NewRuntimeLLMHTTPClient creates an upstream client that bounds the wait for response headers without imposing a total deadline on streaming responses.

func RegisterJupyterRoutes

func RegisterJupyterRoutes(app *echo.Echo, opts JupyterOptions)

func RegisterRuntimeLLMFacadeRoutes

func RegisterRuntimeLLMFacadeRoutes(app *echo.Echo, opts RuntimeLLMOptions)

func RegisterWorkspaceRoutes

func RegisterWorkspaceRoutes(app *echo.Echo, opts WorkspaceOptions)

func ToWorkspaceHTTPError

func ToWorkspaceHTTPError(err error) error

func ToWorkspaceUploadHTTPError

func ToWorkspaceUploadHTTPError(err error) error

func WriteRuntimeLLMEncodedError

func WriteRuntimeLLMEncodedError(c echo.Context, raw []byte, status int) error

Types

type EgressProxy

type EgressProxy struct {
	// contains filtered or unexported fields
}

EgressProxy is the daemon-side forward proxy a sandbox's outbound traffic passes through. It authenticates the sandbox, decides the destination against that sandbox's current policy, and only then opens the connection, so the declared policy is enforced by the engine instead of by a driver feature.

It is an HTTP forward proxy: it accepts absolute-form requests and CONNECT tunnels. It is not an open proxy — a request without a sandbox credential is answered 407 and never decided.

func NewEgressProxy

func NewEgressProxy(options EgressProxyOptions) (*EgressProxy, error)

NewEgressProxy validates the required dependencies and returns the proxy.

func (*EgressProxy) ServeHTTP

func (p *EgressProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the forward-proxy surface. Every decision it makes — including a refusal that comes from the engine rather than from the declared policy — is accounted for through the recorder, because a blocked attempt is exactly what an operator needs to see.

type EgressProxyAuthorizer

type EgressProxyAuthorizer interface {
	AuthorizeEgressProxy(ctx context.Context, claimedSandboxID, credential string) (sandboxID string, err error)
}

EgressProxyAuthorizer resolves the sandbox a proxy credential belongs to. It receives the sandbox name the caller claimed so an implementation can verify the credential against that identity rather than trusting either half alone. A credential that names no sandbox (unknown, revoked, expired, malformed) is an error: the proxy never decides for an unidentified caller.

type EgressProxyOptions

type EgressProxyOptions struct {
	Authorizer      EgressProxyAuthorizer
	Policies        EgressProxyPolicySource
	SessionPolicies EgressProxySessionPolicySource
	Recorder        EgressProxyRecorder
	Logger          *slog.Logger
	// LookupIP resolves the destination of a request. It defaults to the
	// process resolver; a test injects one so a decision never depends on real
	// name resolution.
	LookupIP func(ctx context.Context, host string) ([]net.IP, error)
	// DialTimeout bounds the connection this proxy opens on the sandbox's
	// behalf. Zero uses DefaultEgressDialTimeout.
	DialTimeout time.Duration
	// Dial opens the upstream connection. It is nil in production, where the
	// proxy uses its own dialer; a test injects one to exercise the decision
	// and forwarding paths without reaching a real network.
	Dial func(ctx context.Context, network, address string) (net.Conn, error)
	// TLSMITM enables L7 TLS termination for an HTTPS allowance that declares
	// methods or paths. It is opt-in: with it off, such an allowance fails
	// closed rather than being forwarded uninspected.
	TLSMITM bool
	// CACertificatePEM and CAKeyPEM are the CA the proxy signs leaves with. When
	// both are empty and TLSMITM is true, the proxy generates an ephemeral CA.
	CACertificatePEM []byte
	CAKeyPEM         []byte
	// UpstreamTLSConfig is the base TLS configuration for the connection the
	// proxy opens to the real upstream after intercepting. Nil uses the system
	// roots. A test supplies a pool that trusts its local upstream certificate.
	UpstreamTLSConfig *tls.Config
}

EgressProxyOptions configures an EgressProxy. Authorizer and Policies are required; the remaining fields have production defaults.

type EgressProxyPolicySource

type EgressProxyPolicySource interface {
	EgressProxyPolicy(ctx context.Context, sandboxID string) (egress.Policy, error)
}

EgressProxyPolicySource returns the egress policy that currently governs one sandbox. The proxy reads it per request rather than caching it for the life of a tunnel, which is what makes a policy change take effect on a sandbox that is already running.

type EgressProxyRecorder

type EgressProxyRecorder interface {
	RecordEgressDecision(ctx context.Context, record egress.Record)
}

EgressProxyRecorder receives one account of every decision. It is optional: a composition without one still enforces, it just does not persist the record.

type EgressProxySessionPolicySource

type EgressProxySessionPolicySource interface {
	EgressProxyPolicyForSession(ctx context.Context, sandboxID, sessionID, marker string) (egress.Policy, error)
}

EgressProxySessionPolicySource is the optional per-run hook: when a caller supplies it, the proxy asks for a policy scoped to the sandbox-init session instead of the sandbox-wide policy. A source that has no per-session policy returns the sandbox policy unchanged, so implementing this interface does not change behavior until a deployment actually stores per-run policies.

type EnsureReadyFunc

type EnsureReadyFunc func(ctx context.Context, sessionID string) (domain.ProxyState, error)

type HTTPDoer

type HTTPDoer interface {
	Do(*http.Request) (*http.Response, error)
}

type JupyterOptions

type JupyterOptions struct {
	BasePath    string
	Store       Store
	EnsureReady EnsureReadyFunc
	// Logger receives the readiness and upstream failures that the handler does
	// not return to the client. It defaults to slog.Default.
	Logger *slog.Logger
}

type RuntimeLLMConnectionResolver

type RuntimeLLMConnectionResolver func(ctx context.Context, connectionID, model string) (llms.ResolvedTarget, error)

RuntimeLLMConnectionResolver resolves the upstream target of the connection a facade token is bound to, for one literal upstream model.

The token names the connection, so a proxied call never selects one: it looks up the connection the run was prepared with and forwards the requested model to it. That is what makes the daemon a weak caller — it holds an address and a credential, and the upstream decides which models it serves.

type RuntimeLLMOptions

type RuntimeLLMOptions struct {
	Tokens      RuntimeLLMTokenStore
	Sandboxes   RuntimeLLMSandboxStore
	Connections RuntimeLLMConnectionResolver
	Client      HTTPDoer
	// MaxOutputTokens, when > 0, is injected into every proxied upstream LLM
	// request using the field names supported by the upstream protocol. codex
	// does not send max_output_tokens itself, so without this API proxies that
	// default to a small limit silently truncate long outputs.
	MaxOutputTokens int
	// Logger records why a proxied call failed. The guest receives a fixed
	// message, so the log is the only place the cause survives. Defaults to
	// slog.Default.
	Logger *slog.Logger
}

type RuntimeLLMSandboxStore

type RuntimeLLMSandboxStore interface {
	GetSandbox(context.Context, string) (*domain.Sandbox, error)
}

type RuntimeLLMTokenStore

type RuntimeLLMTokenStore interface {
	GetLLMFacadeToken(context.Context, string) (llms.FacadeToken, error)
}

type Store

type Store interface {
	GetProxyState(id string) (domain.ProxyState, error)
}

type WorkspaceFilesResponse

type WorkspaceFilesResponse struct {
	WorkspaceID string                 `json:"workspace_id"`
	Files       []workspaces.FileEntry `json:"files"`
}

type WorkspaceLoader

type WorkspaceLoader func(ctx context.Context, workspaceID string) (domain.WorkspaceConfig, workspaces.FileWorkspaceContent, error)

type WorkspaceOptions

type WorkspaceOptions struct {
	UploadLimitBytes int64
	Load             WorkspaceLoader
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL