Documentation
¶
Overview ¶
Package tool is the one contract for every workload a sensor runs: a target scanner, a connector to a vendor API, a parser of a file or an enricher of findings.
Stability: Stable (docs/STABILITY.md).
A tool is a manifest plus a run function:
- the Manifest (a tool.yaml file, apiVersion openctem.io/tool/v1) declares what the tool is: its execution class, its intrusiveness tier, the CTIS types it consumes and produces, a typed configuration schema, the permissions it needs (network, filesystem, credentials), its resources and its self-test fixtures;
- Run(ctx, task) does the work and reports through ctx: records through an Emitter that checks each one as it is emitted, progress, logs, artifacts and the outcome of each target, and returns a categorized Error when it fails.
The runtime (pkg/sensorkit) never calls Run in its own process. A Go tool compiled into a sensor runs in a separate, sandboxed process (the sensor re-executes itself), speaking the same adapter protocol a tool in any other language speaks (pkg/tool/adapter). Only pkg/testkit calls Run in-process, applying the same rules the runtime applies, so a tool that would be stopped in production fails its unit test.
The runtime owns every guarantee: it admits targets against the policy, validates the configuration against the manifest's schema, delivers only the credentials the manifest declares, checks every record again on its side of the process boundary (CTIS validity, declared output types, size and count limits, control characters) and stamps the provenance. Nothing in this package lets tool code skip any of it.
The design is docs/rfcs/sensor-sdk-v2.md.
Index ¶
- Constants
- Variables
- func AdapterProtocolJSONSchema() []byte
- func ArgvPlaceholders(element string) []string
- func AuthFailure(err error) error
- func CapDetail(s string) string
- func CheckTaskContent(m Manifest, task Task, root string) ([]string, error)
- func DecodeConfig[C any](schema *core.SettingsSchema, raw json.RawMessage) (C, error)
- func Dial(ctx context.Context, network, address string) (net.Conn, error)
- func EgressProxy() *url.URL
- func Evidence(kind, label string, data map[string]any) (ctis.EvidenceItem, error)
- func Failed(err error) error
- func HTTPExchange(req *http.Request, reqBody []byte, resp *http.Response, respBody []byte, ...) (ctis.EvidenceItem, bool)
- func ImporterFormats() []string
- func Invalid(format string, args ...any) error
- func LoadMappingFile(dir, rel, want string) (*mapping.Mapping, error)
- func ManifestJSONSchema() []byte
- func RateLimit(after time.Duration, err error) error
- func Refused(reason string) error
- func Retry(err error) error
- func SchemaFor[C any]() (json.RawMessage, error)
- func Unreachable(err error) error
- type ArgForm
- type Builder
- func (b *Builder) BatchTargets(max int) *Builder
- func (b *Builder) Build() (Tool, error)
- func (b *Builder) Capabilities(ids ...string) *Builderdeprecated
- func (b *Builder) Class(c Class) *Builder
- func (b *Builder) Describe(s string) *Builder
- func (b *Builder) Handle(h Handler) *Builder
- func (b *Builder) Implements(refs ...string) *Builder
- func (b *Builder) ImplementsWith(im Implementation) *Builder
- func (b *Builder) Manifest(edit func(m *Manifest)) *Builder
- func (b *Builder) MustBuild() Tool
- func (b *Builder) Params(ps ...*Param) *Builder
- func (b *Builder) Produces(kinds ...string) *Builder
- func (b *Builder) Targets(types ...string) *Builder
- func (b *Builder) Tier(t Tier) *Builder
- func (b *Builder) Timeout(d time.Duration) *Builder
- type ByteSize
- type Class
- type ContentPack
- type ContentSlot
- type Context
- type CredentialReq
- type Deprecation
- type Duration
- type Emit
- type Emitter
- type Engine
- type Error
- type ErrorClass
- type Features
- type Filesystem
- type Fixture
- type HTTPSpec
- type Handler
- type Implementation
- type Input
- type InputSpec
- type Issue
- type Job
- type Manifest
- func (m Manifest) ApplyParams(task Task) (Task, error)
- func (m Manifest) Batches() bool
- func (m Manifest) Canonical() ([]byte, error)
- func (m Manifest) ConfigSchema() (*core.SettingsSchema, error)
- func (m Manifest) Contract() *core.ToolContract
- func (m Manifest) Declares(kind, typ string) bool
- func (m Manifest) Digest() string
- func (m Manifest) Implementation(ref string) (Implementation, bool)
- func (m Manifest) ImplementedCapabilities() []capability.Capability
- func (m Manifest) MinimumTier() Tier
- func (m Manifest) Normalized() Manifest
- func (m Manifest) RetestFeature() bool
- func (m Manifest) Slot(name string) (ContentSlot, bool)
- func (m Manifest) Validate() error
- type ManifestError
- type ManifestErrors
- type Mode
- type Network
- type NoConfig
- type OutputSpec
- type Param
- func (p *Param) Default(v any) *Param
- func (p *Param) Help(s string) *Param
- func (p *Param) Label(s string) *Param
- func (p *Param) MaxItems(n int) *Param
- func (p *Param) MaxLength(n int) *Param
- func (p *Param) OneOf(vals ...any) *Param
- func (p *Param) Pattern(re string) *Param
- func (p *Param) PerScan() *Param
- func (p *Param) Range(lo, hi float64) *Param
- func (p *Param) Required() *Param
- type ParamMapping
- type Permissions
- type Presentation
- type Range
- type Repo
- type ReportInfo
- type ReportInfoMetadata
- type Resources
- type RetestContext
- type RetestItem
- type RetestVerdict
- type Retester
- type RunSpec
- type SDKRequirement
- type Safety
- type Scope
- type Secret
- func (s Secret) Format(f fmt.State, _ rune)
- func (s Secret) GoString() string
- func (s Secret) IsZero() bool
- func (s Secret) LogValue() slog.Value
- func (s Secret) MarshalJSON() ([]byte, error)
- func (s Secret) MarshalText() ([]byte, error)
- func (s Secret) Reveal() string
- func (s Secret) String() string
- type Status
- type TLSSpec
- type Target
- type TargetState
- type Task
- type TaskContent
- type Tier
- type Tool
- type Validator
- type Value
- func (v Value) Bool() bool
- func (v Value) BoolOr(d bool) bool
- func (v Value) Float() float64
- func (v Value) FloatOr(d float64) float64
- func (v Value) Int() int
- func (v Value) IntOr(d int) int
- func (v Value) IsSet() bool
- func (v Value) String() string
- func (v Value) StringOr(d string) string
- func (v Value) Strings() []string
- type Verdict
- type VerdictReport
Constants ¶
const ( ContentDefault = "default" ContentCustom = "custom" ContentMerge = "merge" )
Content compositions (api RFC-061 §3.3).
const ( // BatchOne: one target per task (the default). BatchOne = "one" // BatchList: a list of targets per task. BatchList = "list" )
Batch shapes.
const ( SideEffectIOCInLogs = "ioc_in_logs" SideEffectArtifactsOnTarget = "artifacts_on_target" SideEffectStateChange = "state_change" SideEffectAccountLockout = "account_lockout" SideEffectServiceDisruption = "service_disruption" SideEffectThirdPartyContacts = "third_party_contact" )
Side effects a tool may declare.
const ( // ProxyHonors: the tool sends its traffic through the zone's proxy. ProxyHonors = "honors" // ProxyIgnores: the tool connects directly; it is ineligible in a zone // that requires a proxy. ProxyIgnores = "ignores" )
Proxy behaviors.
const ( // ProfileAdapter: the program speaks adapter protocol v1. ProfileAdapter = "adapter" // ProfileExec: a CLI that writes CTIS or SARIF, with no adapter code. ProfileExec = "exec" )
Run profiles.
const ( OutputCTIS = "ctis" OutputSARIF = "sarif" OutputJSONLCTIS = "jsonl-ctis" )
Output formats of the exec profile.
const ( DefaultTimeout = 60 * time.Minute DefaultIdleTimeout = 10 * time.Minute DefaultMaxOutputBytes = 64 << 20 DefaultMaxRecords = 200000 )
Defaults of Resources.
const ( KindAsset = "asset" KindFinding = "finding" KindDependency = "dependency" // KindEndpoint is a method and path a web origin serves (CTIS 1.6 // endpoints[]). KindEndpoint = "endpoint" )
Produce kinds.
const ( OutputJSON = "json" OutputJSONL = "jsonl" )
Output formats of the exec profile that need a mapping file (run.output.mapping): any JSON document or JSON Lines output, turned into CTIS by the declarative mapping language of ctis/importer/mapping.
const ( RetestFinding = "finding" RetestAsset = "asset" )
Retest item kinds.
const APIVersion = "openctem.io/tool/v1"
APIVersion is the manifest format this package reads and writes.
const EnvEgressProxy = "OPENCTEM_EGRESS_PROXY"
EnvEgressProxy is set by the sensor's sandbox, for a task whose network it confines, to the task's forwarder (api RFC-060): the task has no other way out. Its value is a proxy URL ("http://127.0.0.1:1080") that takes HTTP CONNECT, absolute-form HTTP and SOCKS5.
const MaxErrorDetail = 256
MaxErrorDetail bounds Error.Detail on the wire.
const MaxManifestBytes = 256 << 10
MaxManifestBytes bounds a tool.yaml file.
const MaxMappingBytes = 256 << 10
MaxMappingBytes bounds a mapping file.
const MaxRetestItems = 1000
MaxRetestItems bounds the items of one retest task.
const MaxVerdictEvidence = 5
MaxVerdictEvidence bounds the evidence items of one verdict.
const ProtocolVersion = 1
ProtocolVersion is the adapter protocol version this SDK speaks.
const Redacted = "[REDACTED]"
Redacted is what a Secret prints.
Variables ¶
var ( // ErrUndeclaredOutput: the record's kind is not in Manifest.Produces. // The record is quarantined (not delivered). ErrUndeclaredOutput = errors.New("undeclared output type") // ErrOutputLimit: the task reached Resources.MaxRecords or // MaxOutputBytes. The tool should stop; the task ends partial. ErrOutputLimit = errors.New("output limit reached") // ErrInvalidRecord: the record is not valid CTIS. ErrInvalidRecord = errors.New("invalid CTIS record") // ErrUndeclaredCredential: the tool asked for a credential its manifest // does not declare, or one the operator did not store. ErrUndeclaredCredential = errors.New("credential not declared or not granted") )
Errors the emitter returns.
var ErrEgressRefused = errors.New("egress refused")
ErrEgressRefused is the error of a connection the task's forwarder refused: the destination is not one the task may reach.
var ErrRetestRecord = errors.New("tool: a retest task reports verdicts, not records")
ErrRetestRecord is the error of a record emitted in a retest task.
var KnownContentKinds = []string{"nuclei-templates", "semgrep-rules", "yara-rules", "vuln-db", "wordlist", "signatures"}
KnownContentKinds are the kinds the platform manages packs for; a tool's own kind is namespaced (x-<vendor>/<kind>).
Functions ¶
func AdapterProtocolJSONSchema ¶
func AdapterProtocolJSONSchema() []byte
AdapterProtocolJSONSchema returns the JSON Schema of one adapter protocol v1 message, for implementations in other languages.
func ArgvPlaceholders ¶ added in v0.19.0
ArgvPlaceholders returns the placeholder names in an argv element.
func CheckTaskContent ¶ added in v0.19.0
CheckTaskContent checks a task's content against the manifest: every slot declared, its mode supported, its selectors understood, every pack a sha256 digest whose path is an absolute path beneath root (the sensor's content cache). It returns the paths to grant the task.
func DecodeConfig ¶
func DecodeConfig[C any](schema *core.SettingsSchema, raw json.RawMessage) (C, error)
DecodeConfig validates raw against schema (nil: no configuration), fills the defaults and decodes it into C, refusing unknown keys.
func Dial ¶ added in v0.19.0
Dial opens a connection for a tool that speaks TCP itself (a port scanner, a TLS checker, a protocol probe). On a sensor that confines the task's network it goes through the task's forwarder with HTTP CONNECT: a direct connection has no route there, and a destination that is not a target fails with ErrEgressRefused. Elsewhere it is a direct connection. network must be "tcp", "tcp4" or "tcp6".
func EgressProxy ¶ added in v0.19.0
EgressProxy is the task's forwarder, or nil when the task's network is not confined.
func Evidence ¶ added in v0.19.0
Evidence is an evidence item of a kind this CTIS version does not know, its fields in data (at most ctis.MaxEvidenceDataBytes as JSON). Known kinds have their own fields: build them with HTTPExchange or the ctis builders.
func HTTPExchange ¶ added in v0.19.0
func HTTPExchange(req *http.Request, reqBody []byte, resp *http.Response, respBody []byte, match ...ctis.EvidenceMatch) (ctis.EvidenceItem, bool)
HTTPExchange is an http_exchange evidence item of one request and the response it got (resp nil: none arrived). reqBody and respBody are the bodies as sent and received (a body already read from resp). match are the spans that matched, with byte offsets into the bodies.
A body over the CTIS cap keeps a window around the first response-body match (the head without one); matches outside the window are dropped. content_sha256 covers the full captured exchange. ok is false without a request or a response.
func ImporterFormats ¶ added in v0.19.0
func ImporterFormats() []string
ImporterFormats are the named formats an exec-profile tool may write: the formats of ctis/importer, parsed with no code in the tool.
func LoadMappingFile ¶ added in v0.19.0
LoadMappingFile reads the mapping file of an exec-profile manifest from dir: JSON or YAML, a regular file inside dir (no symlink), at most MaxMappingBytes. When want is set the mapping's digest must equal it, so a file changed after the manifest was loaded is refused.
func ManifestJSONSchema ¶
func ManifestJSONSchema() []byte
ManifestJSONSchema returns the JSON Schema of tool.yaml (draft 2020-12), for editors and for implementations in other languages. Validate checks more than the schema can express (class against permissions, placeholders against the config schema, no secrets in config).
func SchemaFor ¶
func SchemaFor[C any]() (json.RawMessage, error)
SchemaFor derives a configuration schema (the settings schema subset) from C's struct tags; nil when C has no fields. The output is deterministic.
func Unreachable ¶
Unreachable reports that a target did not answer (retried next run).
Types ¶
type ArgForm ¶ added in v0.19.0
type ArgForm int
ArgForm is how a {{config.<key>}} placeholder of an exec argv expands.
const ( // ArgScalar, {{config.k}}: the value ("" when the key is not set). ArgScalar ArgForm = iota // ArgOptional, {{config.k?}}: the value; the whole argv element is // left out when the key is not set, empty or false. ArgOptional // ArgList, {{config.k...}}: an array key. As the whole element, one // argument per item; inside a larger element, the items joined with // commas. Left out when the list is empty or not set. ArgList // ArgSwitch, {{config.k?:-flag}}: a boolean key. The whole element // becomes the literal flag when the key is true and is left out // otherwise. ArgSwitch )
Forms of a config placeholder.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder declares a simple tool without writing a manifest by hand:
var Dotenv = tool.Define("dotenv", "1.0.0").
Describe("Finds .env files a web server serves").
Targets("http_service", "domain").
Produces("finding:misconfiguration").
Params(
tool.StringParam("path").Label("Path").Default("/.env").Pattern("^/").MaxLength(256),
tool.IntParam("timeout").Label("Timeout (s)").Default(10).Range(1, 60),
).
Handle(func(ctx tool.Context, job *tool.Job, emit tool.Emit) error {
for _, t := range job.Targets() {
// ... probe t.URL(job.Param("path").String()) ...
_ = emit.Misconfiguration(t, tool.Issue{RuleID: "dotenv-exposed", Title: ".env is readable", Severity: "high"})
ctx.TargetDone(t)
}
return nil
}).
MustBuild()
The result is an ordinary Tool: the same manifest checks, the same runtime guarantees (out-of-process execution, admission, output checks, provenance) and the same tests (pkg/testkit) as a tool written with New. Fields the builder has no method for are set with Manifest.
func Define ¶
Define starts a tool declaration. The defaults are the target-scan class and tier T1 (active, non-intrusive); Class and Tier change them.
func (*Builder) BatchTargets ¶ added in v0.19.0
BatchTargets makes the tool take a list of at most max targets per task (0: the runtime's default).
func (*Builder) Capabilities
deprecated
func (*Builder) Implements ¶ added in v0.19.0
Implements declares the capabilities the tool implements, by reference with their major ("vuln.templates@1"). A standard param of the capability maps to the tool's parameter of the same name when the tool declares one of a matching type; ImplementsWith maps them explicitly.
func (*Builder) ImplementsWith ¶ added in v0.19.0
func (b *Builder) ImplementsWith(im Implementation) *Builder
ImplementsWith declares an implemented capability with an explicit param mapping and output shape.
func (*Builder) Manifest ¶
Manifest edits the manifest directly, for the fields the builder has no method for (permissions, credentials, resources, self-tests, modes).
func (*Builder) MustBuild ¶
MustBuild is Build for a package-level declaration: an invalid tool compiled into a sensor must stop it at start, not run.
func (*Builder) Params ¶
Params declares the tool's parameters: they become the manifest's configuration schema, which the platform renders as a form and the runtime enforces.
func (*Builder) Produces ¶
Produces declares the output types ("finding:<type>", "asset:<type>", "dependency"). A record of any other type is refused.
type ByteSize ¶
type ByteSize int64
ByteSize is a size in bytes; in a manifest a number or a string with a binary or decimal suffix ("512Mi", "1Gi", "64MB").
func ParseByteSize ¶
ParseByteSize reads "1024", "512Ki", "512Mi", "1Gi", "64MB", "1G".
func (*ByteSize) UnmarshalJSON ¶
UnmarshalJSON reads a number or a size string.
type Class ¶
type Class string
Class is a tool's execution class: what it touches and how the runtime dispatches it.
const ( // TargetScan touches customer targets (hosts, URLs, repositories). TargetScan Class = "target-scan" // Connector reads a vendor API with credentials. Connector Class = "connector" // Parser reads a file and produces records; no network. Parser Class = "parser" // Enricher annotates findings; it never creates assets. Enricher Class = "enricher" )
Execution classes.
type ContentPack ¶ added in v0.19.0
type ContentPack struct {
// Digest is the pack's content address ("sha256:<hex>").
Digest string `json:"digest"`
// Source is where the pack came from (platform, tenant).
Source string `json:"source,omitempty"`
// Path is where the sensor keeps it, read-only for the task. Set by
// the sensor's content cache, never taken from a job.
Path string `json:"path,omitempty"`
}
ContentPack is one immutable pack.
type ContentSlot ¶ added in v0.19.0
type ContentSlot struct {
// Slot names the slot in the tool ("templates").
Slot string `json:"slot"`
// Kind is what the content is: a known kind (nuclei-templates,
// semgrep-rules, yara-rules, vuln-db, wordlist, signatures) or a
// tool's own, namespaced (x-acme/rules). Packs bind to tools by kind.
Kind string `json:"kind"`
// Format is dir (default), file or archive.
Format string `json:"format,omitempty"`
// Default is bundled (the platform's managed pack of this kind is
// used unless a step says otherwise) or none.
Default string `json:"default,omitempty"`
// Modes are the compositions the tool supports: default, custom and
// merge (default: all three).
Modes []string `json:"modes,omitempty"`
// Selectors are the filters the tool understands: tags, ids,
// severities, paths.
Selectors []string `json:"selectors,omitempty"`
// MaxBytes bounds a pack of this slot (0: the sensor's limit).
MaxBytes int64 `json:"max_bytes,omitempty"`
}
ContentSlot is a kind of content a tool reads: templates, rules, signatures, a wordlist, a vulnerability database (tool.yaml content; api RFC-061). A tool declares its slots and never fetches content itself: the sensor resolves each task's packs (by digest, from the platform) and the task gets read-only paths to exactly those.
type Context ¶
type Context interface {
context.Context
// Log is a structured logger. Values are redacted (Secret prints
// [REDACTED]) and the runtime bounds the rate and size of what it
// keeps.
Log() *slog.Logger
// Progress reports done of total units (throttled by the runtime).
Progress(done, total int, msg string)
// Emit is the record channel. Each record is checked when it is
// emitted.
Emit() Emitter
// TargetDone reports that the tool finished a target.
TargetDone(t Target)
// TargetError reports that a target failed (its scan coverage); err
// is categorized like a Run error.
TargetError(t Target, err error)
// TargetSkipped reports that the tool did not work on a target.
TargetSkipped(t Target, reason string)
// Artifact creates a size-capped artifact (a raw log, a screenshot),
// delivered separately from the records.
Artifact(name, mediaType string) (io.WriteCloser, error)
// Workdir is the task's private directory, removed after the task.
Workdir() string
// Secret returns a credential the manifest declares and the operator
// stored; anything else is ErrUndeclaredCredential.
Secret(name string) (Secret, error)
// HTTP is a client that reaches only what the manifest's network
// permission allows: the task's targets (NetTargets), the vendor
// hosts (NetVendor) or nothing (NetNone); it never reaches cloud
// metadata endpoints. It is defense in depth: the sandbox backend's
// network class is the boundary. On a sensor that confines the
// task's network it goes through the task's forwarder (EgressProxy).
// Requests carry the User-Agent "openctem-<tool>/<version>" unless the
// tool sets its own. A tool that speaks TCP itself uses Dial.
HTTP() *http.Client
}
Context is what a running tool gets from the runtime. It is canceled on cancel, on the task's deadline and on the sensor's kill switch.
type CredentialReq ¶
type CredentialReq struct {
// Name is how the tool asks for it (Context.Secret).
Name string `json:"name"`
Kind string `json:"kind"`
Required bool `json:"required,omitempty"`
Description string `json:"description,omitempty"`
}
CredentialReq is a credential a tool declares.
type Deprecation ¶ added in v0.19.0
type Deprecation struct {
Since string `json:"since"`
ReplacedBy string `json:"replaced_by,omitempty"`
Message string `json:"message,omitempty"`
}
Deprecation marks a tool version that is being replaced.
type Duration ¶
Duration is a time.Duration; in a manifest a string such as "20m" or a number of seconds.
func (Duration) MarshalJSON ¶
MarshalJSON writes the duration as a string ("20m0s").
func (*Duration) UnmarshalJSON ¶
UnmarshalJSON reads "20m", "1h30m" or a number of seconds.
type Emit ¶
type Emit struct {
// contains filtered or unexported fields
}
Emit builds CTIS records for the common cases and sends them through the task's emitter, which checks each one (CTIS validity, declared output types, limits). CTIS returns the emitter for anything else.
func (Emit) Asset ¶
Asset emits a discovered asset of a CTIS type ("domain", "ip_address", "http_service", ...).
func (Emit) Misconfiguration ¶
Misconfiguration emits a misconfiguration finding on target t.
type Emitter ¶
type Emitter interface {
// Asset emits an asset.
Asset(a ctis.Asset) error
// Finding emits a finding of target t. A finding without an asset
// reference is filed on t's asset.
Finding(t Target, f ctis.Finding) error
// Dependency emits a dependency (SBOM component) found on t.
Dependency(t Target, d ctis.Dependency) error
// Endpoint emits a method and path a web origin serves (CTIS 1.6).
// A URL in it never carries a query value or credentials.
Endpoint(e ctis.Endpoint) error
// Report emits every record of a report (the output of a converter),
// plus its tool, metadata and properties (ReportInfo).
Report(r *ctis.Report) error
}
Emitter is the record channel. Every call checks the record at once, so a tool learns about a bad record at the line that produced it:
- it must be valid CTIS (required fields, enums, ranges);
- its kind must be in Manifest.Produces, else ErrUndeclaredOutput (the record is quarantined, the task ends partial);
- the task's record count and bytes must stay within the resources, else ErrOutputLimit (the tool should stop);
- control and bidirectional-override characters are removed and long strings cut;
- provenance (which tool, version, sandbox, sensor, task) is stamped by the runtime, never taken from the tool.
The runtime repeats every check on its side of the process boundary.
type Engine ¶ added in v0.19.0
type Engine struct {
Name string `json:"name"`
License string `json:"license,omitempty"`
// MinVersion: an older probed engine reports the tool as outdated.
MinVersion string `json:"min_version,omitempty"`
// VersionProbe is the argv that prints the engine's version (no
// shell, no placeholders).
VersionProbe []string `json:"version_probe,omitempty"`
}
Engine is the program a tool wraps. Its version is probed at run time, never trusted from the descriptor.
type Error ¶
type Error struct {
Class ErrorClass
// Retryable defaults from Class; a tool may only turn it off.
Retryable bool
RetryAfter time.Duration
// Detail is a short, human description. The runtime redacts it and
// caps it at MaxErrorDetail bytes before it leaves the sensor.
Detail string
// Err is the cause, for local logs only; it is never sent.
Err error
}
Error is a categorized tool error.
type ErrorClass ¶
type ErrorClass string
ErrorClass categorizes an error, so the platform can tell a retry from a refusal from a broken tool.
const ( // InvalidInput: the configuration or targets are wrong; not retried. InvalidInput ErrorClass = "invalid_input" // TargetUnreachable: a target did not answer; retried on the next run. TargetUnreachable ErrorClass = "target_unreachable" // RefusedByPolicy: the scope or the local policy refused it; the job // goes back to the queue for another sensor. RefusedByPolicy ErrorClass = "refused_by_policy" // Transient: retry with back-off. Transient ErrorClass = "transient" // RateLimited: retry after RetryAfter. RateLimited ErrorClass = "rate_limited" // AuthFailed: a connector's credentials were refused. AuthFailed ErrorClass = "auth_failed" // PermissionDenied: the credentials lack a permission. PermissionDenied ErrorClass = "permission_denied" // NotFound: the resource does not exist. NotFound ErrorClass = "not_found" // ToolError: the tool failed; not retried by default. A plain error // returned from Run is a ToolError. ToolError ErrorClass = "tool_error" )
Error classes a tool may return.
const ( Timeout ErrorClass = "timeout" Canceled ErrorClass = "canceled" ResourceExhausted ErrorClass = "resource_exhausted" OutputRejected ErrorClass = "output_rejected" ToolCrashed ErrorClass = "tool_crashed" // EgressRefused: the sensor's network confinement refused every // connection the tool made toward a target (a target's class only). EgressRefused ErrorClass = "egress_refused" )
Error classes set by the runtime only; a tool that returns one gets ToolError instead.
func (ErrorClass) Retryable ¶
func (c ErrorClass) Retryable() bool
Retryable is the class's default retry verdict.
func (ErrorClass) RuntimeOnly ¶
func (c ErrorClass) RuntimeOnly() bool
RuntimeOnly reports whether c is set by the runtime only.
func (ErrorClass) Valid ¶
func (c ErrorClass) Valid() bool
Valid reports whether c is a class a tool may return.
type Features ¶ added in v0.19.0
type Features struct {
// Retest: the tool can check again what it reported (see Retester).
Retest bool `json:"retest,omitempty"`
// Cancel: the tool stops promptly on a cancel message.
Cancel bool `json:"cancel,omitempty"`
// WebScope: the tool keeps every request inside the job's web scope
// (Task.WebScope): it maps the scope onto its own flags, or requests
// only through Context.HTTP, which enforces it. A job with a web scope
// is refused for a networked tool that does not declare it.
WebScope bool `json:"web_scope,omitempty"`
// Streaming is reserved: feeding records to the next stage while the
// task runs is not part of protocol v1.
Streaming bool `json:"streaming,omitempty"`
}
Features are optional protocol features a tool supports.
type Filesystem ¶
type Filesystem string
Filesystem is what a tool may read besides its private directory.
const ( // FSWorkdir: the task's private directory only (the default). FSWorkdir Filesystem = "workdir" // FSScanRootsReadOnly: also the sensor's scan roots, read-only. FSScanRootsReadOnly Filesystem = "scan-roots-read-only" )
Filesystem permissions.
type Fixture ¶
type Fixture struct {
Name string `json:"name"`
Task string `json:"task"`
Expect string `json:"expect"`
}
Fixture is one self-test: a task file and the CTIS it must produce, both relative to the manifest's directory.
type HTTPSpec ¶ added in v0.19.0
type HTTPSpec struct {
// UserAgent replaces the default "openctem-<tool>/<version>".
UserAgent string `json:"user_agent,omitempty"`
// Headers are added to every request that does not set them.
Headers map[string]string `json:"headers,omitempty"`
// Timeout bounds one request (1s to 10m; default 5m).
Timeout Duration `json:"timeout,omitempty"`
// TLS adjusts TLS toward the targets.
TLS *TLSSpec `json:"tls,omitempty"`
}
HTTPSpec is how a tool's requests to its targets look (tool.yaml http; api RFC-060 §4.4): a tool may set these freely. What a request may reach is not among them: the scope, the sandbox and the forwarder decide that.
type Handler ¶
Handler does the work of one task of a tool declared with Define. job holds the task and its parameters (validated, defaults filled); emit builds CTIS records.
type Implementation ¶ added in v0.19.0
type Implementation struct {
// Capability is the capability reference with its major
// ("scan.ports@1").
Capability string `json:"capability"`
// Params maps the capability's standard params this tool accepts to
// its own config keys. A standard param not listed is one the tool
// does not take: a workflow node that sets it cannot run this tool.
Params map[string]ParamMapping `json:"params,omitempty"`
// OutputShape names which of the capability's accepted output shapes
// the tool emits, when the capability has several.
OutputShape string `json:"output_shape,omitempty"`
}
Implementation is one capability a tool implements.
type Input ¶
type Input struct {
Name string `json:"name"`
MediaType string `json:"media_type"`
// Path is relative to the task's directory.
Path string `json:"path"`
Size int64 `json:"size,omitempty"`
SHA256 string `json:"sha256,omitempty"`
}
Input is a file given to the task (a parser's input).
type InputSpec ¶ added in v0.19.0
type InputSpec struct {
// Batch is BatchOne (default) or BatchList.
Batch string `json:"batch,omitempty"`
// MaxTargets bounds a list task (BatchList only).
MaxTargets int `json:"max_targets,omitempty"`
}
InputSpec is how a tool takes its targets.
type Issue ¶
type Issue struct {
RuleID string
Title string
Severity ctis.Severity
Description string
// Evidence is the proof (a response excerpt, a banner); never a
// secret value.
Evidence string
// CVE is the vulnerability's CVE id (Vulnerability only).
CVE string
}
Issue is a finding in a few fields. Severity is critical, high, medium, low or info.
type Job ¶
type Job struct {
Task
// contains filtered or unexported fields
}
Job is one task of a tool declared with Define, with typed access to its targets and parameters.
type Manifest ¶
type Manifest struct {
// APIVersion is APIVersion ("" in Go code means APIVersion).
APIVersion string `json:"apiVersion"`
// Name is unique per sensor: ^[a-z][a-z0-9-]{1,62}$.
Name string `json:"name"`
// Version is the semantic version of the tool adapter (not of the
// engine it runs).
Version string `json:"version"`
Description string `json:"description,omitempty"`
// Publisher is who publishes the tool: the signer of a certified
// tool, or free text (shown as text, never trusted).
Publisher string `json:"publisher,omitempty"`
// License is the SPDX license expression of the adapter (the wrapped
// engine's is engine.license).
License string `json:"license,omitempty"`
// Engine is the program the tool wraps; its version is probed.
Engine *Engine `json:"engine,omitempty"`
// Presentation is how the platform shows the tool.
Presentation *Presentation `json:"presentation,omitempty"`
Class Class `json:"class"`
// Modes the tool runs in; empty means both.
Modes []Mode `json:"modes,omitempty"`
// Tier is the tier the tool asks for. It cannot be below the tier
// floor of a capability it implements; the platform assigns the
// effective tier and may raise it (MinimumTier).
Tier Tier `json:"tier"`
// Implements are the capabilities of the OpenCTEM capability taxonomy
// the tool implements ("scan.ports@1"), with its param mapping.
Implements []Implementation `json:"implements,omitempty"`
// Capabilities is the older free-form capability list. Deprecated:
// use Implements. With Implements set it may only repeat its ids.
Capabilities []string `json:"capabilities,omitempty"`
// Consumes are CTIS asset types, "file:<media type>" for parsers, or
// "finding:<type>" for enrichers.
Consumes []string `json:"consumes,omitempty"`
// Produces are "asset:<type>", "finding:<type>" or "dependency". A
// record of any other kind is refused (ErrUndeclaredOutput).
Produces []string `json:"produces"`
// Input is how the tool takes its targets (default: one per task).
Input *InputSpec `json:"input,omitempty"`
// Config is the tool's configuration schema: the closed JSON Schema
// subset of api RFC-038 (pkg/core settings schemas), with no secret
// fields (secrets are credentials, never configuration). nil: no
// configuration (New derives one from the config type when it has
// fields).
Config json.RawMessage `json:"config,omitempty"`
Permissions Permissions `json:"permissions"`
Resources Resources `json:"resources"`
// Safety is what the tool does to its targets beyond reading them.
Safety *Safety `json:"safety,omitempty"`
// Features are the optional protocol features the tool supports.
Features *Features `json:"features,omitempty"`
// HTTP is how the tool's requests to its targets look (user agent,
// headers, timeout, TLS): applied by ctx.HTTP(), named in exec argv
// ({{http.user_agent}}) and readable by an adapter from its manifest.
HTTP *HTTPSpec `json:"http,omitempty"`
// Content are the kinds of content the tool reads (templates, rules,
// wordlists): the task gets the resolved packs (api RFC-061).
Content []ContentSlot `json:"content,omitempty"`
// Selftest are fixtures: a task and the CTIS it must produce.
Selftest []Fixture `json:"selftest,omitempty"`
// Retest says the tool can check again what it reported (a retest
// task, see Retester). Target-scan tools only. Deprecated spelling of
// features.retest.
Retest bool `json:"retest,omitempty"`
// Protocol is the range of adapter protocol versions the tool speaks.
Protocol Range `json:"protocol"`
// Run says how to start a tool that is not compiled into the sensor.
Run *RunSpec `json:"run,omitempty"`
// SDK is the oldest SDK that understands every key this manifest uses.
SDK *SDKRequirement `json:"sdk,omitempty"`
// Deprecated marks a tool being replaced.
Deprecated *Deprecation `json:"deprecated,omitempty"`
}
Manifest describes a tool. Its file form is tool.yaml; LoadManifest reads it, strictly (an unknown key is an error: the manifest is a security document). The runtime trusts the manifest file or the one compiled into the sensor, never a tool's description of itself.
func LoadManifest ¶
LoadManifest reads a manifest (YAML or JSON) strictly: unknown keys, duplicate keys and more than one document are errors. The result is validated (Validate) and has its defaults filled.
func LoadManifestFile ¶
LoadManifestFile reads and validates a tool.yaml file.
func (Manifest) ApplyParams ¶ added in v0.19.0
ApplyParams maps a task's standard params onto the tool's config keys, through the implements entry of the task's capability, and returns the task with Params cleared and Config set. Every value is checked against the capability's param (type, enum, bounds) and against the tool's narrowing (values, min, max); a param the tool does not map, a value it does not support and a config key the task also sets to another value are invalid_input. Nothing is dropped silently.
A task without a capability must carry no params. A capability the tool does not implement is invalid_input.
func (Manifest) Batches ¶ added in v0.19.0
Batches reports whether the tool takes a list of targets per task.
func (Manifest) ConfigSchema ¶
func (m Manifest) ConfigSchema() (*core.SettingsSchema, error)
ConfigSchema parses the configuration schema (nil when there is none).
func (Manifest) Contract ¶
func (m Manifest) Contract() *core.ToolContract
Contract names the manifest in the sensor manifest (core.ToolContract): its digest and the fields the platform plans with.
func (Manifest) Declares ¶
Declares reports whether the manifest produces records of kind ("asset", "finding", "dependency") and CTIS type typ ("" for dependencies).
func (Manifest) Digest ¶
Digest is "sha256:" + the hex SHA-256 of the manifest's canonical JSON (defaults filled, object members sorted, no insignificant whitespace). The runtime compares a tool's self-description with its file by digest, and the sensor registers manifests with the platform by digest.
func (Manifest) Implementation ¶ added in v0.19.0
func (m Manifest) Implementation(ref string) (Implementation, bool)
Implementation returns the implements entry of a capability reference ("scan.ports@1").
func (Manifest) ImplementedCapabilities ¶ added in v0.19.0
func (m Manifest) ImplementedCapabilities() []capability.Capability
ImplementedCapabilities returns the capabilities the tool implements, in declaration order. A reference that does not resolve is skipped (Validate refuses it).
func (Manifest) MinimumTier ¶ added in v0.19.0
MinimumTier is the lowest tier the tool can be assigned: the highest of its declared tier, the tier floors of the capabilities it implements, and T2 when it declares a side effect. The platform may assign a higher one; never a lower one.
func (Manifest) Normalized ¶
Normalized returns the manifest with its defaults filled, as the runtime sees it.
func (Manifest) RetestFeature ¶ added in v0.19.0
RetestFeature reports whether the tool can retest (features.retest or the older top-level retest key).
func (Manifest) Slot ¶ added in v0.19.0
func (m Manifest) Slot(name string) (ContentSlot, bool)
Slot returns a declared content slot.
func (Manifest) Validate ¶
Validate checks the manifest: identity, class against permissions and tier, consumes/produces from the CTIS vocabulary, a configuration schema in the settings subset with no secret fields, resources within bounds, and a run specification with a closed set of placeholders and no shell. The error is ManifestErrors with every problem.
type ManifestError ¶
ManifestError is one problem in a manifest. Path is a JSON pointer.
func (ManifestError) Error ¶
func (e ManifestError) Error() string
type ManifestErrors ¶
type ManifestErrors []ManifestError
ManifestErrors are every problem found in a manifest.
func (ManifestErrors) Error ¶
func (e ManifestErrors) Error() string
type Network ¶
type Network string
Network is the network a tool needs.
const ( // NetNone: no network at all. NetNone Network = "none" // NetTargets: the task's targets only, through the zone's egress. NetTargets Network = "targets" // NetResolver: DNS questions about the task's targets only, answered // through the sensor's resolvers; no connection to any host, the // targets included. A DNS resolution tool that never contacts the // target hosts declares it. NetResolver Network = "resolver" // NetEgressProxy: through the sensor's egress proxy only. NetEgressProxy Network = "egress-proxy" // NetVendor: the declared vendor hosts only. NetVendor Network = "vendor" )
Network permissions.
type NoConfig ¶
type NoConfig struct{}
NoConfig is the configuration type of a tool without configuration.
type OutputSpec ¶
type OutputSpec struct {
// Format is OutputCTIS, OutputSARIF, OutputJSONLCTIS, OutputJSON or
// OutputJSONL (with Mapping), or a named format of ctis/importer
// (ImporterFormats: "nuclei", "trivy", "cyclonedx", ...).
Format string `json:"format"`
// From is "stdout" or "file" (the {{task.output}} path).
From string `json:"from"`
// Mapping is the mapping file (relative to the manifest's directory)
// that turns json or jsonl output into CTIS: the declarative mapping
// language of ctis/importer/mapping, in JSON or YAML.
Mapping string `json:"mapping,omitempty"`
// MappingDigest is the mapping's digest, set when the manifest file is
// loaded (LoadManifestFile); the manifest digest covers it, and the
// runtime refuses a mapping file that no longer matches it.
MappingDigest string `json:"mapping_digest,omitempty"`
}
OutputSpec is an exec-profile tool's output.
type Param ¶
type Param struct {
// contains filtered or unexported fields
}
Param is one parameter of a tool declared with Define. Its methods set what the platform shows (Label, Help) and what the runtime enforces (Default, Range, OneOf, Pattern, MaxLength, MaxItems, Required).
func (*Param) PerScan ¶
PerScan lets a scan set the parameter (otherwise only the tool's settings on the sensor or platform do).
type ParamMapping ¶ added in v0.19.0
type ParamMapping struct {
// Key is the top-level config key; empty means the param's own name.
Key string `json:"key,omitempty"`
// Values narrows an enum param (or the items of a list param) to the
// values the tool supports. A value outside makes the tool ineligible
// for that node; it is never silently dropped.
Values []string `json:"values,omitempty"`
// Min and Max narrow an integer param.
Min *int `json:"min,omitempty"`
Max *int `json:"max,omitempty"`
}
ParamMapping maps one standard param to a config key, optionally narrowing the values the tool supports.
func (ParamMapping) ConfigKey ¶ added in v0.19.0
func (p ParamMapping) ConfigKey(param string) string
ConfigKey is the config key the param maps to.
type Permissions ¶
type Permissions struct {
// Network defaults by class: none for parsers and enrichers, targets
// for target scans, vendor for connectors.
Network Network `json:"network,omitempty"`
// VendorHosts are the hosts a vendor-network tool may reach
// ("api.example.com", "api.example.com:8443", or "${config.<key>}" for
// a string configuration key holding a URL or host).
VendorHosts []string `json:"vendor_hosts,omitempty"`
Filesystem Filesystem `json:"filesystem,omitempty"`
// Credentials the tool may receive. Only these are ever delivered,
// and only when the sensor's operator stored them.
Credentials []CredentialReq `json:"credentials,omitempty"`
// LinuxCaps the tool needs (NET_RAW for SYN scans); granted only when
// the local policy allows.
LinuxCaps []string `json:"linux_caps,omitempty"`
// Proxy is ProxyHonours or ProxyIgnores; unset is unknown, which the
// platform treats as ignores where a zone requires a proxy.
Proxy string `json:"proxy,omitempty"`
}
Permissions are what a tool needs. The effective permission is the manifest's intersected with the sensor's policy and the job.
type Presentation ¶ added in v0.19.0
type Presentation struct {
DisplayName string `json:"display_name,omitempty"`
Category string `json:"category,omitempty"`
Icon string `json:"icon,omitempty"`
DocsURL string `json:"docs_url,omitempty"`
}
Presentation is how the platform shows a tool. Every string is rendered as text; the icon is a name from a closed set, never a URL, and the docs URL is a link the platform never fetches.
type Repo ¶
type Repo struct {
URL string `json:"url,omitempty"`
Branch string `json:"branch,omitempty"`
Commit string `json:"commit,omitempty"`
DefaultBranch bool `json:"default_branch,omitempty"`
PullRequest int `json:"pull_request,omitempty"`
}
Repo is a CI task's repository.
type ReportInfo ¶
type ReportInfo struct {
Tool *ctis.Tool `json:"tool,omitempty"`
Metadata *ReportInfoMetadata `json:"metadata,omitempty"`
Properties ctis.Properties `json:"properties,omitempty"`
}
ReportInfo is what a report carries besides its records: the tool's vendor and capabilities, metadata such as the coverage type and branch, and properties. The runtime keeps the tool's name as the manifest's.
func InfoOf ¶
func InfoOf(r *ctis.Report) *ReportInfo
InfoOf returns the ReportInfo of r (nil when r carries none).
type ReportInfoMetadata ¶
type ReportInfoMetadata struct {
ID string `json:"id,omitempty"`
DurationMs int `json:"duration_ms,omitempty"`
SourceRef string `json:"source_ref,omitempty"`
SourceType string `json:"source_type,omitempty"`
CoverageType string `json:"coverage_type,omitempty"`
Branch *ctis.BranchInfo `json:"branch,omitempty"`
Scope *ctis.Scope `json:"scope,omitempty"`
Properties ctis.Properties `json:"properties,omitempty"`
}
ReportInfoMetadata is the part of a report's metadata a tool may set.
type Resources ¶
type Resources struct {
CPU float64 `json:"cpu,omitempty"`
Memory ByteSize `json:"memory,omitempty"`
Timeout Duration `json:"timeout,omitempty"`
IdleTimeout Duration `json:"idle_timeout,omitempty"`
MaxOutputBytes ByteSize `json:"max_output_bytes,omitempty"`
MaxRecords int `json:"max_records,omitempty"`
// Cost is the slot cost for the sensor's capacity model.
Cost int `json:"cost,omitempty"`
}
Resources bound one task of the tool. Zero fields take the runtime's defaults.
type RetestContext ¶
type RetestContext interface {
Context
// Verdict reports the verdict on item. The first verdict of an item
// counts; a verdict on an item not in the task is ignored. detail is
// cut to MaxErrorDetail and redacted.
Verdict(item RetestItem, v Verdict, detail string)
// Report is Verdict with the attempt's evidence and the digest of the
// check that ran. Evidence over MaxVerdictEvidence items or invalid
// makes the verdict Unverifiable.
Report(item RetestItem, r VerdictReport)
}
RetestContext is the Context of a retest task.
type RetestItem ¶
type RetestItem struct {
// Ref is the platform's opaque id of the item, echoed in its verdict.
Ref string `json:"ref"`
// Target is the ref of the task target the item is on.
Target string `json:"target"`
// Kind is RetestFinding or RetestAsset.
Kind string `json:"kind"`
// RuleID is the check that reported the finding (a template id, a rule
// id).
RuleID string `json:"rule_id,omitempty"`
// Fingerprint is the finding's fingerprint as the platform keeps it.
Fingerprint string `json:"fingerprint,omitempty"`
// Attrs are typed hints from the platform.
Attrs map[string]string `json:"attrs,omitempty"`
}
RetestItem is one thing the platform asks the tool to check again.
type RetestVerdict ¶
type RetestVerdict struct {
Ref string `json:"ref"`
Verdict Verdict `json:"verdict"`
Detail string `json:"detail,omitempty"`
// Evidence is what the attempt saw (at most MaxVerdictEvidence items),
// sensitive values marked (ctis.MarkSensitive), never masked.
Evidence []ctis.EvidenceItem `json:"evidence,omitempty"`
// TemplateDigest identifies the exact check that ran (a template's
// digest), so the platform can tell a fix from a changed check.
TemplateDigest string `json:"template_digest,omitempty"`
}
RetestVerdict is an item's final verdict, as the runtime reports it.
type Retester ¶
type Retester interface {
Retest(ctx RetestContext, task Task) error
}
Retester is implemented by a tool that can retest (Manifest.Retest). The runtime calls Retest instead of Run for a retest task.
type RunSpec ¶
type RunSpec struct {
// Profile is ProfileAdapter (default) or ProfileExec.
Profile string `json:"profile,omitempty"`
// Argv is the program and its arguments. Never a shell. Placeholders
// are a closed set: {{config.<key>}} (a scalar key of the config
// schema) and its forms {{config.<key>?}} (left out when not set),
// {{config.<key>...}} (an array key: one argument per item, or
// comma-joined inside a larger argument) and {{config.<key>?:-flag}}
// (a boolean key: the flag when true; see ConfigArg), {{target.value}},
// {{target.host}}, {{target.port}}, {{target.url}},
// {{task.targets_file}}, {{task.targets_json}}, {{task.config_file}},
// {{task.web_scope_file}}, {{task.output}}, {{task.workdir}}.
Argv []string `json:"argv"`
// Output is where an exec-profile tool writes its results.
Output *OutputSpec `json:"output,omitempty"`
// ExitCodes maps an exec-profile tool's exit codes to outcomes
// ("ok", "partial") or error classes; default: 0 ok, else tool_error.
ExitCodes map[string]string `json:"exit_codes,omitempty"`
}
RunSpec says how the runtime starts a tool that is its own program.
type SDKRequirement ¶ added in v0.19.0
type SDKRequirement struct {
Min string `json:"min,omitempty"`
}
SDKRequirement is the oldest SDK that understands every key a descriptor uses.
type Safety ¶ added in v0.19.0
type Safety struct {
// RateParam is the integer config key that bounds requests or packets
// per second; the runtime caps it by the sensor's local policy.
RateParam string `json:"rate_param,omitempty"`
// SideEffects the tool may cause. Any entry makes the tool intrusive
// (tier T2).
SideEffects []string `json:"side_effects,omitempty"`
// ExpandsTargets: the tool discovers new targets. They go to the
// platform as assets; the tool never scans them in the same task.
ExpandsTargets bool `json:"expands_targets,omitempty"`
}
Safety says what a tool does to its targets beyond reading them.
type Scope ¶
type Scope struct {
Includes []string `json:"includes,omitempty"`
Excludes []string `json:"excludes,omitempty"`
}
Scope is a job's scope.
type Secret ¶
type Secret struct {
// contains filtered or unexported fields
}
Secret is a credential. It prints, formats, logs and marshals as [REDACTED]; Reveal returns the value, and the SDK never logs it.
func (Secret) MarshalJSON ¶
MarshalJSON writes "[REDACTED]".
func (Secret) MarshalText ¶
MarshalText writes [REDACTED].
type Status ¶
type Status string
Status is how a task ended.
const ( // StatusOK: every target done. StatusOK Status = "ok" // StatusPartial: some targets failed, or output was capped or // quarantined. StatusPartial Status = "partial" // StatusFailed: the task failed. StatusFailed Status = "failed" // StatusCanceled: the task was canceled. StatusCanceled Status = "canceled" )
Task outcomes.
type TLSSpec ¶ added in v0.19.0
type TLSSpec struct {
// InsecureSkipVerify accepts any certificate (scanning a target with a
// self-signed or expired one). Refused for a vendor-network tool:
// credentials travel to vendor hosts.
InsecureSkipVerify bool `json:"insecure_skip_verify,omitempty"`
// MinVersion is "1.0", "1.1", "1.2" or "1.3" (default: Go's).
MinVersion string `json:"min_version,omitempty"`
}
TLSSpec adjusts TLS toward a tool's targets.
func (*TLSSpec) TLSMinVersion ¶ added in v0.19.0
TLSMinVersion maps MinVersion to crypto/tls (0: Go's default).
type Target ¶
type Target struct {
// Ref is an opaque reference that links records to the platform's
// asset.
Ref string `json:"ref"`
// Type is a CTIS asset type ("http_service", "domain", "repository").
Type string `json:"type,omitempty"`
// Value is the target itself ("https://a.example:8443", "10.0.4.7",
// "/src").
Value string `json:"value"`
// Attrs are typed hints from the platform (port, scheme, tech, ...).
Attrs map[string]string `json:"attrs,omitempty"`
}
Target is one thing to work on.
type TargetState ¶
type TargetState string
TargetState is the outcome of one target.
const ( StateDone TargetState = "done" StateFailed TargetState = "failed" StateSkipped TargetState = "skipped" )
Target outcomes.
type Task ¶
type Task struct {
ID string `json:"id"`
Attempt int `json:"attempt,omitempty"`
Deadline time.Time `json:"deadline,omitzero"`
Targets []Target `json:"targets,omitempty"`
// Config is the effective configuration (defaults applied).
Config json.RawMessage `json:"config,omitempty"`
// Inputs are files placed in the task's directory (parsers).
Inputs []Input `json:"inputs,omitempty"`
// Repo is the repository of a runner-mode (CI) task.
Repo *Repo `json:"repo,omitempty"`
// Scope is the job's scope, read-only, for tools that expand targets.
// Expanded targets are emitted as assets, never scanned in the same
// task.
Scope Scope `json:"scope,omitzero"`
// Local is configuration the sensor itself supplies for a tool compiled
// into it (operator settings, managed content paths): never from the
// platform, never for an adapter shipped on its own.
Local json.RawMessage `json:"local,omitempty"`
// Retest, when not empty, makes the task a retest: the items to check
// again, each on one of Targets (see Retester).
Retest []RetestItem `json:"retest,omitempty"`
// Capability is the capability the task runs ("scan.ports@1"), one the
// tool implements. The runtime checks the output against its contract.
Capability string `json:"capability,omitempty"`
// Params are the capability's standard params as the workflow set
// them. The runtime maps them onto the tool's config keys
// (Manifest.ApplyParams) before the tool starts; the tool reads only
// Config and never receives Params.
Params map[string]json.RawMessage `json:"params,omitempty"`
// MaxTier is the highest tier the job allows (the ceiling of the
// platform grant). A tool whose MinimumTier is higher is refused.
MaxTier Tier `json:"max_tier,omitempty"`
// WebScope, when set, is the hosts, paths and methods a web tool may
// request (webscope.Scope). Context.HTTP refuses every request outside
// it; a tool that makes its own requests declares features.web_scope
// and keeps to it.
WebScope *webscope.Scope `json:"web_scope,omitempty"`
// Limits are the port, protocol and path limits of the targets (from
// the job's verified signed statement; scopelimit). The tool host
// enforces them outside the tool: the task's egress forwarder refuses
// a connection to a limited host on another port and an HTTP request
// outside its path prefixes. A task with limits runs only on a sandbox
// that confines its network.
Limits []scopelimit.Limit `json:"limits,omitempty"`
// HTTP is the effective http settings of the task: the manifest's,
// with what the sensor's local policy decides (a forced User-Agent).
// Set by the runtime, never taken from a job; ctx.HTTP() applies it.
HTTP *HTTPSpec `json:"http,omitempty"`
// OrgHTTP is the organization's HTTP policy from the job. The tool host
// merges it into HTTP (after the local policy) and clears it; a tool
// never acts on it.
OrgHTTP *core.OrgHTTPPolicy `json:"-"`
// Content are the task's content packs per slot the manifest
// declares, resolved by the sensor to read-only paths (ContentPaths).
Content []TaskContent `json:"content,omitempty"`
}
Task is one unit of work. Its targets were admitted by the runtime and its configuration validated against the manifest's schema before the tool sees it.
func (Task) ContentPaths ¶ added in v0.19.0
ContentPaths are the paths of a slot's packs in the task (none when the task has no content for it).
type TaskContent ¶ added in v0.19.0
type TaskContent struct {
Slot string `json:"slot"`
// Mode is default, custom or merge.
Mode string `json:"mode,omitempty"`
// Packs are the packs, in order (a merge: custom after default).
Packs []ContentPack `json:"packs,omitempty"`
// Selectors filter the content (tags, ids, severities, paths).
Selectors map[string][]string `json:"selectors,omitempty"`
}
TaskContent is one slot's content for a task, resolved by the sensor.
type Tier ¶
type Tier string
Tier is a tool's intrusiveness.
type Tool ¶
type Tool interface {
// Manifest describes the tool. It is static: the runtime reads it
// before any tool code runs.
Manifest() Manifest
// Run does the work of one task.
Run(ctx Context, task Task) error
}
Tool is the one contract for every workload a sensor runs.
func New ¶
New builds a Tool from a manifest and a typed run function. C is the tool's configuration: the runtime validates the task's configuration against the manifest's schema, then the tool decodes it into C (defaults filled, unknown keys refused).
When m.Config is nil and C has fields, the schema is derived from C's struct tags: json (the key), default, min, max, enum (comma-separated), pattern, maxLength, maxItems, title, description, scope ("scan" lets a scan set the key), required ("true"). A field tagged secret:"true" is refused: secrets are credentials, never configuration.
New panics when the manifest is invalid: a tool compiled into a sensor with a broken manifest must stop the sensor at start, not run.
func WithRetest ¶
func WithRetest(t Tool, fn func(ctx RetestContext, task Task) error) Tool
WithRetest returns t with a retest handler: the manifest declares Retest, Run is t's, Retest is fn. It panics without a tool or a handler, like New on an invalid manifest.
type Validator ¶
Validator is optional: semantic checks beyond the manifest's schemas, run before any target is touched.
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value is a parameter's value. The runtime validated it against the parameter's declaration, so the typed accessors only fall back when the parameter is unset (no default) or of another type.
type Verdict ¶
type Verdict string
Verdict is what a retest concluded about one item.
const ( // StillPresent: the issue (or asset) was observed again. StillPresent Verdict = "still_present" // Fixed: the check ran against the reached target and the issue is // gone (an asset: it no longer exists). Fixed Verdict = "fixed" // Unverifiable: the tool could not tell (unreachable, check not // available, error). Unverifiable Verdict = "unverifiable" )
Verdicts.
type VerdictReport ¶ added in v0.19.0
type VerdictReport struct {
Verdict Verdict
Detail string
Evidence []ctis.EvidenceItem
TemplateDigest string
}
VerdictReport is a verdict with what supports it (RetestContext.Report).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package adapter runs a tool (pkg/tool) as an adapter process: the tool's side of adapter protocol v1, newline-delimited JSON on stdin and stdout, one task per process (docs/rfcs/sensor-sdk-v2.md, D.4.2).
|
Package adapter runs a tool (pkg/tool) as an adapter process: the tool's side of adapter protocol v1, newline-delimited JSON on stdin and stdout, one task per process (docs/rfcs/sensor-sdk-v2.md, D.4.2). |
|
Package toolcompat runs code written against the older interfaces (core.Scanner, core.Collector) as tools of the tool contract (pkg/tool), so it gets the contract's runtime without a rewrite: out-of-process execution in the task sandbox, admission against the policy, declared credentials only, checked and stamped output.
|
Package toolcompat runs code written against the older interfaces (core.Scanner, core.Collector) as tools of the tool contract (pkg/tool), so it gets the contract's runtime without a rewrite: out-of-process execution in the task sandbox, admission against the policy, declared credentials only, checked and stamped output. |