client

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package client dials a remote plimsolld and adapts it to sandbox.Sandbox, so isolated calls can swap providers behind the same interface. RPC capabilities use operation-specific named server profiles, not raw grants. Keyless by default; set WithToken to authenticate against a fail-closed server (the token needs the code:run scope).

Index

Constants

View Source
const Protocol = protocol.Number

Protocol is the wire protocol number this client speaks (protocol.Number). It is stamped on every request; a daemon on another number refuses the request before reading its payload.

Variables

View Source
var (
	// ErrInvalidBaseURL marks malformed, relative, or non-HTTP(S) endpoints.
	ErrInvalidBaseURL = errors.New("client: invalid plimsoll base URL")
	// ErrInsecureHTTP marks a non-loopback cleartext endpoint that was not
	// explicitly authorized with WithInsecureHTTP.
	ErrInsecureHTTP = errors.New("client: cleartext HTTP to a non-loopback plimsoll requires WithInsecureHTTP")
)
View Source
var ErrNotRecorded = errors.New("client: the run executed but was not recorded")

ErrNotRecorded means a run executed and returned its result, but the Recorder failed to keep it.

View Source
var ErrProtocolMismatch = errors.New("client: the daemon serves a different protocol number than this client")

ErrProtocolMismatch means the daemon serves a different protocol number than this client speaks (Protocol). The daemon refused before reading the payload, so nothing ran; the fix is to run matching versions, not to retry.

View Source
var ErrRawGrantUnsupported = errors.New("client: a raw HostAPIGrant cannot be sent over RPC; configure an operation-specific named grant profile")

ErrRawGrantUnsupported prevents a capability-bearing in-process request from being silently downgraded to an isolated remote run. RPC grants are server-held named profiles selected with the operation-specific options below.

View Source
var ErrResultKindMismatch = errors.New("client: the daemon's result is not of the request's kind")

ErrResultKindMismatch means the daemon answered a request of one kind with a result of another (or none). Execution may already have happened, so it is reported as DataLoss and is never a safe retry signal.

Functions

func NewTraceContext

func NewTraceContext(ctx context.Context, id string) context.Context

NewTraceContext returns ctx carrying an opaque correlation id that RunJavaScript and RunProject will send with the run. The daemon records it on that run's audit line and does nothing else with it, which lets a caller JOIN plimsoll's metadata-only record to its own record of the same request — the reason plimsoll can decline to keep a second copy of the path and body without leaving "which record did the agent read" unanswerable.

It is a context value rather than a client Option because the id is per REQUEST, not per connection: one embedded client serves many runs, and a connection-scoped id would stamp them all the same. That also matches where such an id already lives: an upstream MCP proxy can carry one across its boundary, and its server can pass that same value to NewTraceContext.

The id must be opaque: [A-Za-z0-9._:-] up to 64 bytes, or the server drops it. Put no meaning in it. The meaning belongs in the caller's log.

func TraceIDFrom

func TraceIDFrom(ctx context.Context) string

TraceIDFrom returns the correlation id carried by ctx, or "". A run without one is the normal case for a caller that does not correlate its logs.

Types

type Info

type Info struct {
	Sandbox                  string
	Isolation                sandbox.IsolationClass
	SupportsProject          bool
	SupportsModule           bool
	SupportsJavaScriptGrants bool
	SupportsProjectGrants    bool
	// Protocol is the number the daemon serves. Compare it with Protocol before
	// relying on the daemon; every Run request is checked against it again.
	Protocol uint32
	// SupportsSessions says OpenSession works here; the lifetime and idle timeout
	// are the daemon's, which a session may ask to shorten.
	SupportsSessions   bool
	SessionLifetime    time.Duration
	SessionIdleTimeout time.Duration
	// Environments and Resources are the daemon's informational statements (see
	// sandbox.PayloadEnvironment): configuration, never attestation, and enforced
	// by nothing. Equal identities mean the same software; an empty one claims nothing.
	Environments sandbox.Environments
	Resources    sandbox.Resources
}

Info is a remote plimsolld's self-description: which provider is active, its isolation tier, and whether RunProject works there.

type Option

type Option func(*config)

Option configures a Remote.

func WithConnectOptions

func WithConnectOptions(o ...connect.ClientOption) Option

WithConnectOptions passes extra connect client options (e.g. gRPC, gzip).

func WithHTTPClient

func WithHTTPClient(c connect.HTTPClient) Option

WithHTTPClient overrides the HTTP client (default: 6-minute timeout client).

func WithInsecureHTTP

func WithInsecureHTTP() Option

WithInsecureHTTP explicitly permits cleartext HTTP to a non-loopback host. Omit it in production: without this opt-in New fails closed so code:run bearer credentials and submitted source cannot silently cross an unencrypted network.

func WithJavaScriptGrantProfile

func WithJavaScriptGrantProfile(profile string) Option

WithJavaScriptGrantProfile selects a named server-side capability only for RunJavaScript. Grant support differs by operation; applying one profile to every call made isolated project runs fail on providers that only broker snippets.

func WithProjectGrantProfile

func WithProjectGrantProfile(profile string) Option

WithProjectGrantProfile selects a named server-side capability only for RunProject. Call Describe first: no built-in provider currently advertises this capability.

func WithRecorder added in v0.10.0

func WithRecorder(r Recorder) Option

WithRecorder hands every run's checked exchange to r, so a harness can sign and keep it.

func WithToken

func WithToken(token string) Option

WithToken sends "Authorization: Bearer <token>" on every call. Omit it for a keyless (dev/open) server.

type Recorder added in v0.10.0

type Recorder interface {
	Record(req *plimsollv1.RunRequest, resp *plimsollv1.RunResponse) error
}

Recorder receives every run exchange whose record checked: the request as sent and the response as received. A harness outside the daemon signs and stores them (attest.Harness is one). It is called on the calling goroutine before the result returns. An error it returns comes back with the result, wrapped in ErrNotRecorded: the run executed, and only keeping its record failed.

type Remote

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

Remote is a sandbox.Sandbox backed by a remote plimsolld over Connect.

func New

func New(baseURL string, opts ...Option) (*Remote, error)

New returns a checked Remote dialing an absolute HTTP(S) base URL. Loopback HTTP is allowed for local development; cleartext transport to any other host requires the explicit WithInsecureHTTP option.

func (*Remote) Describe

func (r *Remote) Describe(ctx context.Context) (Info, error)

Describe asks the server for its active provider's measured capabilities, so a consumer advertises facts instead of assuming a tier the provider may not honor.

func (*Remote) Exchange added in v0.10.0

Exchange sends a prepared Run request exactly as given (nothing is stamped on it, not even the protocol number) and returns the response with its checked run record, after handing both to the Recorder if one is set. It is for a harness that stores requests and sends them again; RunJavaScript, RunProject and RunModule are the ordinary way to run code. Errors are those of the three run methods.

func (*Remote) IsolationClass

func (r *Remote) IsolationClass() sandbox.IsolationClass

IsolationClass is Unknown: a remote server's provider — and thus its boundary tier — cannot be asserted locally before a call. Each response reports the tier the run actually used (Result.Isolation / ProjectResult.Isolation).

func (*Remote) Name

func (r *Remote) Name() string

func (*Remote) OpenSession added in v0.10.0

func (r *Remote) OpenSession(ctx context.Context, opts SessionOptions) (*Session, error)

OpenSession opens a session. The session ID it holds is a capability: it is sent only to the daemon, and never appears in a record, a log line or an error.

func (*Remote) RunJavaScript

func (r *Remote) RunJavaScript(ctx context.Context, in sandbox.Request) (sandbox.Result, error)

func (*Remote) RunModule added in v0.6.0

RunModule runs a compiled simulator once per row on the remote provider. The request is validated here first, so a malformed table never leaves the process, and the returned isolation evidence is checked against the floor exactly as for the other two operations.

func (*Remote) RunProject

type Session added in v0.10.0

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

Session is an open session on a remote daemon: one sandbox for many calls, in which files persist between calls and no process outlives its call. Calls are serialized by the daemon. The client checks every call's record against the chain it has seen, so a call another holder of the session ID made is caught at the next call (record.ErrChain, as DataLoss).

func (*Session) Close added in v0.10.0

func (s *Session) Close(ctx context.Context) (SessionSummary, error)

Close ends the session (or collects one that ended by itself) and returns the daemon's count of executed calls and last record. When the count or the last record differs from the chain this client has seen, some call it did not make ran in the session: that is DataLoss wrapping record.ErrChain, with the summary. A SessionRecorder signs the daemon's statement either way.

func (*Session) Ended added in v0.10.0

func (s *Session) Ended() error

Ended returns the session's end once a response has reported it, else nil.

func (*Session) Exchange added in v0.10.0

Exchange sends a stored Run request's fields as a call in this session, the session ID filled in: how a harness replays a recorded session into a fresh one (see Remote.Exchange). A module request has no session form and is refused before anything is sent.

func (*Session) ExpiresAt added in v0.10.0

func (s *Session) ExpiresAt() time.Time

ExpiresAt is when the session's lifetime ends.

func (*Session) Fingerprint added in v0.10.0

func (s *Session) Fingerprint() string

Fingerprint is the SHA-256 of the session ID, as the session's records carry it.

func (*Session) IdleTimeout added in v0.10.0

func (s *Session) IdleTimeout() time.Duration

IdleTimeout is how long the session may go without a call before the daemon suspends it (the next call resumes it).

func (*Session) Isolation added in v0.10.0

func (s *Session) Isolation() sandbox.IsolationClass

Isolation is the tier the daemon measured when the session opened.

func (*Session) RunJavaScript added in v0.10.0

func (s *Session) RunJavaScript(ctx context.Context, in sandbox.Request) (sandbox.Result, error)

RunJavaScript runs a snippet in the session.

func (*Session) RunProject added in v0.10.0

RunProject runs a project in the session; its files persist for later calls.

type SessionOptions added in v0.10.0

type SessionOptions struct {
	MinimumIsolation sandbox.IsolationClass
	Software         sandbox.SoftwareRule
	Lifetime         time.Duration
	IdleTimeout      time.Duration
}

SessionOptions is what OpenSession asks for. A zero duration takes the daemon's; a longer one than the daemon's is cut to it.

type SessionRecorder added in v0.10.0

type SessionRecorder interface {
	Recorder
	RecordClose(session string, calls uint64, lastRecordSHA256 string) error
}

SessionRecorder is a Recorder that also signs a session's close: the daemon's count of executed calls and its last record, which lets a verifier tell a complete chain from a cut one. attest.Harness is one.

type SessionSummary added in v0.10.0

type SessionSummary struct {
	Session          string // the fingerprint
	Calls            uint64
	LastRecordSHA256 string
	End              sandbox.SessionEnd // closed, or an earlier end
}

SessionSummary is what CloseSession states about the session's chain.

Jump to

Keyboard shortcuts

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