Documentation
¶
Overview ¶
Package toolrt holds the rules every tool's output passes, shared by the tool side (pkg/tool/adapter, pkg/testkit) and the runtime side (pkg/sensorkit/toolhost): record validation against CTIS and the manifest's produces, sanitization, size and count caps, report assembly and provenance stamping. The runtime applies them on its side of the process boundary whatever the tool did on its own.
Index ¶
- Constants
- Variables
- func CheckEvidenceItems(items []ctis.EvidenceItem) error
- func CheckRetest(m tool.Manifest, task tool.Task) *tool.Error
- func CheckWebScope(m tool.Manifest, task tool.Task) *tool.Error
- func CleanString(s string) string
- func DefaultUserAgent(m tool.Manifest) string
- func EffectiveUserAgent(m tool.Manifest, task tool.Task) string
- func Invoke(t tool.Tool, ctx tool.Context, task tool.Task) error
- func MetadataIP(ip net.IP) bool
- func NewContext(ctx context.Context, cfg ContextConfig) tool.Context
- func NewHTTPClient(m tool.Manifest, task tool.Task) *http.Client
- func Sanitize(raw []byte, out any) error
- func SanitizeValue(v, out any) error
- func SpecOf(m tool.Manifest, task tool.Task) *tool.HTTPSpec
- func Stamp(r *ctis.Report, p Provenance)
- func VendorHosts(m tool.Manifest, config json.RawMessage) []string
- type Assembler
- func (a *Assembler) AddCheckedAsset(as ctis.Asset)
- func (a *Assembler) AddCheckedDependency(d ctis.Dependency)
- func (a *Assembler) AddCheckedEndpoint(e ctis.Endpoint)
- func (a *Assembler) AddCheckedFinding(ref string, f ctis.Finding) error
- func (a *Assembler) Asset(as ctis.Asset) error
- func (a *Assembler) Checker() *Checker
- func (a *Assembler) Dependency(d ctis.Dependency) error
- func (a *Assembler) Done() int
- func (a *Assembler) Endpoint(e ctis.Endpoint) error
- func (a *Assembler) Finding(ref string, f ctis.Finding) error
- func (a *Assembler) LookupTarget(ref string) (tool.Target, bool)
- func (a *Assembler) Report(now time.Time) *ctis.Report
- func (a *Assembler) Results() []TargetResult
- func (a *Assembler) SetInfo(info *tool.ReportInfo)
- func (a *Assembler) Status(runErr *tool.Error) tool.Status
- func (a *Assembler) Target(ref string, state tool.TargetState, err *tool.Error) error
- func (a *Assembler) Unfinished() []tool.Target
- func (a *Assembler) Verdict(ref string, r tool.VerdictReport) error
- func (a *Assembler) Verdicts(runErr *tool.Error) []tool.RetestVerdict
- type Checker
- func (c *Checker) AllowTarget(typ, value string)
- func (c *Checker) Asset(a ctis.Asset) (ctis.Asset, error)
- func (c *Checker) AssetJSON(raw []byte) (ctis.Asset, error)
- func (c *Checker) Dependency(d ctis.Dependency) (ctis.Dependency, error)
- func (c *Checker) DependencyJSON(raw []byte) (ctis.Dependency, error)
- func (c *Checker) Endpoint(e ctis.Endpoint) (ctis.Endpoint, error)
- func (c *Checker) EndpointJSON(raw []byte) (ctis.Endpoint, error)
- func (c *Checker) Finding(f ctis.Finding) (ctis.Finding, error)
- func (c *Checker) FindingJSON(raw []byte) (ctis.Finding, error)
- func (c *Checker) HasAsset(id string) bool
- func (c *Checker) Info(in *tool.ReportInfo) (*tool.ReportInfo, error)
- func (c *Checker) InfoJSON(raw []byte) (*tool.ReportInfo, error)
- func (c *Checker) KnowAsset(id string)
- func (c *Checker) Stats() Stats
- func (c *Checker) TargetAsset(a ctis.Asset) (ctis.Asset, error)
- type ContextConfig
- type Provenance
- type Sink
- type Stats
- type TargetResult
Constants ¶
const ( // MaxString bounds any string in a record (longer ones are cut). MaxString = 256 << 10 // MaxDepth bounds the nesting of a record. MaxDepth = 32 // MaxNodes bounds the values in one record. MaxNodes = 100000 // MaxInfoBytes bounds a report's tool, metadata and properties. MaxInfoBytes = 64 << 10 )
Bounds of one record.
const ( MaxLogMessages = 1000 MaxLogBytes = 1 << 20 )
Log bounds per task.
const ProvenanceKey = "provenance"
ProvenanceKey is the metadata property the runtime stamps (and overwrites whatever a tool put there).
Variables ¶
var ErrHostNotAllowed = errors.New("host not allowed by the tool's network permission")
ErrHostNotAllowed is the error of a request to a host the tool's network permission does not allow.
Functions ¶
func CheckEvidenceItems ¶ added in v0.19.0
func CheckEvidenceItems(items []ctis.EvidenceItem) error
CheckEvidenceItems validates evidence items with the CTIS rules (kind, caps, the shape of known kinds), by validating a minimal report that carries them.
func CheckRetest ¶
CheckRetest checks a retest task's items before it runs: the manifest declares retest, at most tool.MaxRetestItems items with unique refs, a known kind, and each on one of the task's targets (a retest never adds a target). It returns nil for a task that is not a retest.
func CheckWebScope ¶ added in v0.19.0
CheckWebScope refuses a task whose web scope is invalid, or that a networked tool cannot keep to: one that does not declare features.web_scope would run unrestricted. It returns nil for a task without a web scope.
func CleanString ¶
CleanString removes control and bidirectional-override characters (it keeps tab, line feed and carriage return), replaces invalid UTF-8 and cuts the result to MaxString bytes on a rune boundary.
func DefaultUserAgent ¶ added in v0.19.0
DefaultUserAgent is the User-Agent of a tool's requests when the tool sets none: "openctem-<tool>/<version>". A tool sets its own per request (req.Header.Set("User-Agent", ...)).
func EffectiveUserAgent ¶ added in v0.19.0
EffectiveUserAgent is the User-Agent of a task's requests: the effective http.user_agent, else DefaultUserAgent.
func Invoke ¶
Invoke runs one task of t: Retest for a retest task (t must implement tool.Retester, ctx tool.RetestContext), Run otherwise.
func MetadataIP ¶
MetadataIP reports whether ip is link-local or a known cloud metadata address. Tool traffic never goes there.
func NewContext ¶
func NewContext(ctx context.Context, cfg ContextConfig) tool.Context
NewContext returns the tool.Context a tool runs with: its emitter checks every record before the sink sees it, its logger redacts the task's secret values and bounds what it keeps, Secret answers only declared credentials, and HTTP reaches only what the network permission allows.
func NewHTTPClient ¶
NewHTTPClient returns the client of tool.Context.HTTP: it reaches the task's targets (targets, egress-proxy), the vendor hosts (vendor) or nothing (none, resolver), re-checks every redirect, and never dials a link-local or cloud-metadata address whatever a name resolves to.
func Sanitize ¶
Sanitize decodes raw into out after cleaning it: invalid UTF-8 replaced, control characters (but tab, line feed and carriage return) and bidirectional-override characters removed from every string and key, strings cut to MaxString, nesting and size bounded. The final decode is strict: a member out does not know is an error (the platform decodes CTIS strictly too).
func SanitizeValue ¶
SanitizeValue sanitizes a typed value into out (see Sanitize).
func SpecOf ¶ added in v0.19.0
SpecOf is a task's http settings: the effective ones the runtime put in the task, else the manifest's.
func Stamp ¶
func Stamp(r *ctis.Report, p Provenance)
Stamp writes p into r's metadata properties, replacing anything there.
func VendorHosts ¶ added in v0.19.0
func VendorHosts(m tool.Manifest, config json.RawMessage) []string
VendorHosts are the hosts of a manifest's permissions.vendor_hosts, with ${config.<key>} entries read from the task's configuration.
Types ¶
type Assembler ¶
type Assembler struct {
// contains filtered or unexported fields
}
Assembler builds one task's CTIS report from checked records. It is safe for concurrent use.
func NewAssembler ¶
NewAssembler starts the report of task.
func (*Assembler) AddCheckedAsset ¶
AddCheckedAsset adds an asset the checker already accepted.
func (*Assembler) AddCheckedDependency ¶
func (a *Assembler) AddCheckedDependency(d ctis.Dependency)
AddCheckedDependency adds a dependency the checker already accepted.
func (*Assembler) AddCheckedEndpoint ¶ added in v0.19.0
AddCheckedEndpoint adds an endpoint the checker already accepted.
func (*Assembler) AddCheckedFinding ¶
AddCheckedFinding adds a finding the checker already accepted, filing it on target ref's asset when it has no asset reference.
func (*Assembler) Dependency ¶
func (a *Assembler) Dependency(d ctis.Dependency) error
Dependency checks and adds a dependency.
func (*Assembler) Finding ¶
Finding checks and adds a finding; one without an asset reference is filed on target ref's asset (added on first use) when ref names a target.
func (*Assembler) LookupTarget ¶
LookupTarget returns the task's target with ref.
func (*Assembler) Report ¶
Report returns the assembled report. The tool's name is the manifest's (a tool cannot claim to be another one); tool.version is what the tool reported (the engine it runs). The adapter's own version is in the provenance.
func (*Assembler) Results ¶
func (a *Assembler) Results() []TargetResult
Results returns every target's outcome, in task order; a target never reported has no entry.
func (*Assembler) SetInfo ¶
func (a *Assembler) SetInfo(info *tool.ReportInfo)
SetInfo merges a checked ReportInfo (later calls win per field).
func (*Assembler) Status ¶
Status computes the task outcome from the run's error and what the checker and the targets say: a run error is failed (canceled for a cancel); otherwise partial when a target failed, was skipped or was never reported, or when output was capped, quarantined or invalid.
func (*Assembler) Target ¶
Target records target ref's outcome (the first terminal report wins; unknown refs are refused).
func (*Assembler) Unfinished ¶ added in v0.27.0
Unfinished returns the task's targets the tool gave no outcome, in task order: the ones a run that stopped part-way never reached.
func (*Assembler) Verdict ¶
func (a *Assembler) Verdict(ref string, r tool.VerdictReport) error
Verdict records the verdict on item ref (the first one counts). A ref not in the task or an unknown verdict is an error. Evidence the runtime cannot accept (too many items, an invalid item, an unreadable template digest) makes the verdict Unverifiable rather than failing the task: the tool's output is hostile until checked.
func (*Assembler) Verdicts ¶
func (a *Assembler) Verdicts(runErr *tool.Error) []tool.RetestVerdict
Verdicts returns one final verdict per retest item, in task order (nil for a task that is not a retest). The runtime, not the tool, decides what a verdict may claim:
- an item without a verdict is Unverifiable;
- Fixed stands only when the task finished (runErr nil) and the item's target was reported done: a tool that never reached the target, or stopped, cannot call anything fixed.
type Checker ¶
type Checker struct {
// contains filtered or unexported fields
}
Checker applies the output rules to one task's records. It is safe for concurrent use.
func NewChecker ¶
NewChecker returns a checker for m's limits and produces.
func (*Checker) AllowTarget ¶
AllowTarget lets an asset that is one of the task's targets (same type and value) through without being in produces: a converter that files findings on the scanned target emits it, and it is the task's input, not new output.
func (*Checker) AssetJSON ¶
AssetJSON checks an asset given as JSON (from an adapter) and returns it sanitized.
func (*Checker) Dependency ¶
func (c *Checker) Dependency(d ctis.Dependency) (ctis.Dependency, error)
Dependency checks a typed dependency.
func (*Checker) DependencyJSON ¶
func (c *Checker) DependencyJSON(raw []byte) (ctis.Dependency, error)
DependencyJSON checks a dependency given as JSON.
func (*Checker) EndpointJSON ¶ added in v0.19.0
EndpointJSON checks an endpoint given as JSON.
func (*Checker) Finding ¶
Finding checks a typed finding. Its asset_ref, when set, must name an asset accepted earlier (or one the runtime added).
func (*Checker) FindingJSON ¶
FindingJSON checks a finding given as JSON.
func (*Checker) Info ¶
func (c *Checker) Info(in *tool.ReportInfo) (*tool.ReportInfo, error)
Info checks a typed ReportInfo.
func (*Checker) InfoJSON ¶
func (c *Checker) InfoJSON(raw []byte) (*tool.ReportInfo, error)
InfoJSON checks a report's tool, metadata and properties given as JSON.
type ContextConfig ¶
type ContextConfig struct {
Manifest tool.Manifest
Task tool.Task
Sink Sink
// Secrets are the credentials delivered for this task (already
// limited to the declared ones by the runtime).
Secrets map[string]tool.Secret
Workdir string
}
ContextConfig builds a tool.Context.
type Provenance ¶
type Provenance struct {
Tool string `json:"tool"`
ToolVersion string `json:"tool_version"`
ManifestDigest string `json:"manifest_digest"`
Protocol int `json:"protocol,omitempty"`
Execution string `json:"execution"`
Sandbox any `json:"sandbox,omitempty"`
Network string `json:"network,omitempty"`
Sensor string `json:"sensor,omitempty"`
TaskID string `json:"task_id,omitempty"`
Attempt int `json:"attempt,omitempty"`
Status tool.Status `json:"status"`
Records int `json:"records"`
Quarantined map[string]int `json:"quarantined,omitempty"`
Invalid int `json:"invalid,omitempty"`
Capped bool `json:"capped,omitempty"`
// Capability is the capability the task ran ("scan.ports@1").
Capability string `json:"capability,omitempty"`
// ContractViolations counts records that miss its contract.
ContractViolations int `json:"contract_violations,omitempty"`
}
Provenance is what the runtime stamps on every report: which tool and manifest produced it, under which sandbox, for which task, and what the runtime refused.
type Sink ¶
type Sink interface {
Asset(a ctis.Asset) error
// Finding and Dependency name the target ref ("" for none).
Finding(ref string, f ctis.Finding) error
Dependency(ref string, d ctis.Dependency) error
Endpoint(e ctis.Endpoint) error
Info(info *tool.ReportInfo) error
Target(ref string, state tool.TargetState, err *tool.Error)
Progress(done, total int, msg string)
Log(level slog.Level, msg string, attrs map[string]any)
Artifact(name, mediaType string) (io.WriteCloser, error)
// Verdict is a retest verdict on item ref (detail cleaned and redacted).
Verdict(ref string, r tool.VerdictReport)
}
Sink receives what a tool reports. The adapter's sink writes protocol messages; the test kit's feeds an Assembler. Records reach the sink already checked by the context's own checker.
type Stats ¶
type Stats struct {
Records int `json:"records"`
Bytes int64 `json:"bytes"`
Capped bool `json:"capped,omitempty"`
Quarantined map[string]int `json:"quarantined,omitempty"`
Invalid int `json:"invalid,omitempty"`
}
Stats are what the checker refused.
type TargetResult ¶
type TargetResult struct {
Target tool.Target `json:"-"`
State tool.TargetState `json:"state"`
Error *tool.Error `json:"-"`
}
TargetResult is the outcome of one target.