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
- Variables
- func NewTraceContext(ctx context.Context, id string) context.Context
- func TraceIDFrom(ctx context.Context) string
- type Info
- type Option
- func WithConnectOptions(o ...connect.ClientOption) Option
- func WithHTTPClient(c connect.HTTPClient) Option
- func WithInsecureHTTP() Option
- func WithJavaScriptGrantProfile(profile string) Option
- func WithProjectGrantProfile(profile string) Option
- func WithRecorder(r Recorder) Option
- func WithToken(token string) Option
- type Recorder
- type Remote
- func (r *Remote) Describe(ctx context.Context) (Info, error)
- func (r *Remote) Exchange(ctx context.Context, msg *plimsollv1.RunRequest) (*plimsollv1.RunResponse, *sandbox.RunRecord, error)
- func (r *Remote) IsolationClass() sandbox.IsolationClass
- func (r *Remote) Name() string
- func (r *Remote) OpenSession(ctx context.Context, opts SessionOptions) (*Session, error)
- func (r *Remote) RunJavaScript(ctx context.Context, in sandbox.Request) (sandbox.Result, error)
- func (r *Remote) RunModule(ctx context.Context, in sandbox.ModuleRequest) (sandbox.ModuleResult, error)
- func (r *Remote) RunProject(ctx context.Context, in sandbox.ProjectRequest) (sandbox.ProjectResult, error)
- type Session
- func (s *Session) Close(ctx context.Context) (SessionSummary, error)
- func (s *Session) Ended() error
- func (s *Session) Exchange(ctx context.Context, req *plimsollv1.RunRequest) (*plimsollv1.RunResponse, *sandbox.RunRecord, error)
- func (s *Session) ExpiresAt() time.Time
- func (s *Session) Fingerprint() string
- func (s *Session) IdleTimeout() time.Duration
- func (s *Session) Isolation() sandbox.IsolationClass
- func (s *Session) RunJavaScript(ctx context.Context, in sandbox.Request) (sandbox.Result, error)
- func (s *Session) RunProject(ctx context.Context, in sandbox.ProjectRequest) (sandbox.ProjectResult, error)
- type SessionOptions
- type SessionRecorder
- type SessionSummary
Constants ¶
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 ¶
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") )
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.
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.
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.
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 ¶
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 ¶
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 ¶
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 ¶
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
WithRecorder hands every run's checked exchange to r, so a harness can sign and keep it.
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 ¶
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 ¶
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
func (r *Remote) Exchange(ctx context.Context, msg *plimsollv1.RunRequest) (*plimsollv1.RunResponse, *sandbox.RunRecord, error)
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) OpenSession ¶ added in v0.10.0
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 (*Remote) RunModule ¶ added in v0.6.0
func (r *Remote) RunModule(ctx context.Context, in sandbox.ModuleRequest) (sandbox.ModuleResult, error)
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 ¶
func (r *Remote) RunProject(ctx context.Context, in sandbox.ProjectRequest) (sandbox.ProjectResult, error)
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
Ended returns the session's end once a response has reported it, else nil.
func (*Session) Exchange ¶ added in v0.10.0
func (s *Session) Exchange(ctx context.Context, req *plimsollv1.RunRequest) (*plimsollv1.RunResponse, *sandbox.RunRecord, error)
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) Fingerprint ¶ added in v0.10.0
Fingerprint is the SHA-256 of the session ID, as the session's records carry it.
func (*Session) IdleTimeout ¶ added in v0.10.0
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
RunJavaScript runs a snippet in the session.
func (*Session) RunProject ¶ added in v0.10.0
func (s *Session) RunProject(ctx context.Context, in sandbox.ProjectRequest) (sandbox.ProjectResult, error)
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.