Documentation
¶
Overview ¶
Package capkit defines the platform-independent contracts for reusable security capabilities.
The host owns policy: scope, approval, evidence, storage, secrets, audit and rate limiting are injected as ports. Capability kits only depend on this package, never on each other or on a host project.
Index ¶
- Constants
- func ClampSummary(s string) string
- func CursorFor(offset int) string
- func FirstNonEmpty(vals ...string) string
- func FirstPositive(v, fallback int) int
- func PreviewRunes(s string, n int) string
- func ProjectIDFrom(ctx context.Context) int64
- func ShellQuote(s string) string
- func TimeoutFromMS(ms int, def, max time.Duration) time.Duration
- func Truncate(s string, n int) string
- func WithCallContext(ctx context.Context, cc CallContext) context.Context
- type ApprovalRequest
- type Approver
- type ArtifactStore
- type AuditEvent
- type AuditSink
- type AuthFlow
- type AuthFlowFunc
- type BinaryManager
- type BinaryStatus
- type Call
- type CallContext
- type Capability
- type ChainPlanner
- type Clock
- type Completer
- type Credentials
- type Deps
- type Downloader
- type Error
- func AsError(err error) *Error
- func Conflict(msg string) *Error
- func EvidenceWriteFailed(msg string) *Error
- func InvalidInput(msg string) *Error
- func NeedHuman(msg string) *Error
- func NewError(code, message string) *Error
- func NotFound(msg string) *Error
- func ScopeDenied(msg string) *Error
- func TargetUnreachable(msg string) *Error
- func Timeout(msg string) *Error
- func ToolMissing(msg string) *Error
- func Unavailable(msg string) *Error
- func UpstreamError(msg string) *Error
- type EventSpec
- type Evidence
- type EvidenceRef
- type EvidenceSink
- type ExecOpts
- type Fetcher
- type Finding
- type Fingerprint
- type FingerprintProvider
- type HTTPDoer
- type IDGenerator
- type Identity
- type IdentityScope
- type IntelItem
- type IntelQuery
- type IntelSource
- type IntelStore
- type JobRef
- type Limiter
- type Logger
- type Manifest
- type Meta
- type NextStep
- type Output
- type Page
- type Planner
- type PlannerFunc
- type ProcessResult
- type ProcessRunner
- type ProcessSpec
- type RateLimitSpec
- type Registry
- type Request
- type Response
- type Result
- func BlockedResult(err *Error) Result
- func DataResult(v any) (Result, error)
- func FailResult(err error) Result
- func NewResult(status Status, summary string) Result
- func PartialResult(summary string, data any) (Result, error)
- func SuccessResult(summary string, data any) (Result, error)
- func TextResult(text string) Result
- type Risk
- type ScopeChecker
- type Sealer
- type Session
- type SessionInfo
- type SessionManager
- type SessionOpener
- type SessionSpec
- type SettingSpec
- type Settings
- type Spec
- type Status
- type Target
- type TargetKind
- type TemplateCatalog
- type TemplateEngine
- type TemplateQuery
- type TemplateRef
- type TokenSnapshot
- type ToolSpec
- type Tunnel
- type TunnelSpec
- type Tunneler
- type Uploader
Constants ¶
const ( CodeInvalidInput = "bad_input" CodeScopeDenied = "scope_denied" CodeApprovalRequired = "approval_required" CodeNotFound = "not_found" CodeConflict = "conflict" CodeRateLimited = "rate_limited" CodeInternal = "internal" CodeNeedHuman = "need_human" CodeToolMissing = "tool_missing" CodeTargetUnreachable = "target_unreachable" CodeTimeout = "timeout" CodeUpstreamError = "upstream_error" CodeEvidenceWriteFailed = "evidence_write_failed" )
const MaxDataBytes = 8 << 10
MaxDataBytes is the single-call Data ceiling. Oversized payloads are truncated with Truncated=true and the real total reported in Page.Total.
const MaxListItems = 100
MaxListItems is the list length above which results must paginate.
const MaxSummaryRunes = 200
MaxSummaryRunes bounds Summary so an agent can read it directly.
Variables ¶
This section is empty.
Functions ¶
func ClampSummary ¶
ClampSummary trims s to MaxSummaryRunes runes, appending an ellipsis.
func CursorFor ¶
CursorFor renders the opaque cursor that addresses item offset, for tools to hand back in Page.Cursor.
func FirstNonEmpty ¶
FirstNonEmpty returns the first value that is not empty after trimming surrounding whitespace.
func FirstPositive ¶
FirstPositive returns v when it is positive, otherwise fallback.
func PreviewRunes ¶
PreviewRunes returns at most n runes of s, for an EvidenceRef preview (docs §5.5.4: the preview is <=200 characters, and runes — not bytes — are what "characters" means for a Chinese target).
func ProjectIDFrom ¶
ProjectIDFrom returns the project id, or 0 if unset.
func ShellQuote ¶
ShellQuote quotes s for POSIX shells when it contains shell metacharacters. Adapters that build a remote command line should use this; adapters that stream arguments directly (execve over SSH) must not.
func TimeoutFromMS ¶
TimeoutFromMS converts a millisecond budget into a duration, falling back to def when the budget is unset and clamping anything larger than max.
func WithCallContext ¶
func WithCallContext(ctx context.Context, cc CallContext) context.Context
WithCallContext attaches the caller/task context to a request context. The runtime does this before invoking a capability; gate-aware adapters read it for scope/audit decisions.
Types ¶
type ApprovalRequest ¶
type ApprovalRequest struct {
Capability string
Tool string
Risk Risk
Targets []Target
Actor string
ProjectID int64
}
ApprovalRequest is presented to the host before a risky tool runs.
type Approver ¶
type Approver interface {
Require(ctx context.Context, req ApprovalRequest) error
}
Approver is the human/automated approval gate. The runtime requires it for high-risk tools; returning an error denies the call.
type ArtifactStore ¶
type AuditEvent ¶
type AuditEvent struct {
TraceID string `json:"trace_id"`
Actor string `json:"actor"`
ProjectID int64 `json:"project_id"`
TaskID string `json:"task_id,omitempty"`
Capability string `json:"capability"`
Tool string `json:"tool"`
Risk Risk `json:"risk"`
Targets []Target `json:"targets,omitempty"`
Phase string `json:"phase"` // start | finish
Status string `json:"status,omitempty"`
Error string `json:"error,omitempty"`
InputHash string `json:"input_hash,omitempty"`
DurationMS int64 `json:"duration_ms,omitempty"`
EvidenceIDs []string `json:"evidence_ids,omitempty"`
StartedAt time.Time `json:"started_at"`
FinishedAt time.Time `json:"finished_at,omitempty"`
}
type AuditSink ¶
type AuditSink interface {
Record(ctx context.Context, ev AuditEvent)
}
type AuthFlow ¶
type AuthFlow interface {
Kind() string
Login(ctx context.Context, creds Credentials) (Identity, error)
}
AuthFlow performs a site-specific login and returns an Identity. The host implements concrete flows (form/json/oauth/cas/bearer); capkit provides helpers for the common steps.
type AuthFlowFunc ¶
type AuthFlowFunc struct {
KindName string
Fn func(ctx context.Context, creds Credentials) (Identity, error)
}
AuthFlowFunc adapts a function to AuthFlow.
func (AuthFlowFunc) Kind ¶
func (f AuthFlowFunc) Kind() string
func (AuthFlowFunc) Login ¶
func (f AuthFlowFunc) Login(ctx context.Context, creds Credentials) (Identity, error)
type BinaryManager ¶
type BinaryStatus ¶
type Call ¶
type Call struct {
Tool string
Input json.RawMessage
Context CallContext
}
Call is one tool invocation routed by the runtime.
type CallContext ¶
type CallContext struct {
TraceID string `json:"trace_id,omitempty"`
ProjectID int64 `json:"project_id,omitempty"`
TaskID string `json:"task_id,omitempty"`
Actor string `json:"actor,omitempty"`
DryRun bool `json:"dry_run,omitempty"`
}
CallContext carries the caller identity and task context. It never carries raw credentials; secrets are passed through the Sealer/HTTP ports.
func CallContextFrom ¶
func CallContextFrom(ctx context.Context) (CallContext, bool)
CallContextFrom returns the attached call context.
type Capability ¶
type Capability interface {
Manifest() Manifest
Call(ctx context.Context, call Call) (Result, error)
}
Capability is one self-contained capability (http, nuclei, shell, ...). Implementations must be safe for concurrent Call invocations.
type ChainPlanner ¶
type ChainPlanner struct {
Planners []Planner
}
ChainPlanner merges several planners, deduping by tool name (first planner that suggests a tool wins, so order expresses priority).
func (*ChainPlanner) Add ¶
func (c *ChainPlanner) Add(p Planner)
Add appends a planner (nil is ignored).
type Completer ¶ added in v0.5.0
type Completer interface {
Complete(ctx context.Context, system, user string, maxTokens int) (string, error)
}
Completer is the host-provided single-shot text completion port. Kits hold no model credentials and import no provider SDK: the host maps a request to whichever profile is active and applies its own temperature and token budget. A nil Completer means the host has no model configured, and every generation tool reports "unavailable" instead of failing silently.
type Credentials ¶
type Credentials struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Token string `json:"token,omitempty"`
Cookies map[string]string `json:"cookies,omitempty"`
Fields map[string]string `json:"fields,omitempty"`
Actor string `json:"actor,omitempty"`
}
Credentials is the cleartext credential set handed to an AuthFlow. The host resolves these from the Sealer at the edge; kits never persist them.
type Deps ¶
type Deps struct {
Scope ScopeChecker
Approval Approver
Evidence EvidenceSink
HTTP HTTPDoer
Fetcher Fetcher
Limiter Limiter
Audit AuditSink
Settings Settings
Sealer Sealer
Logger Logger
Clock Clock
IDs IDGenerator
Processes ProcessRunner
Artifacts ArtifactStore
Binaries BinaryManager
Fingerprints FingerprintProvider
Templates TemplateCatalog
TemplateEngines map[string]TemplateEngine
Sessions SessionManager
Intel IntelStore
Completer Completer
// ExtraIntel are advisory sources the host fetches itself and wants polled
// through the same store and dedup path as the kit's own sources. See
// IntelSource: this is the seam for sources that need host-specific
// machinery (a JS engine, an authenticated API, a private feed).
ExtraIntel []IntelSource
}
Deps is the full set of host-provided ports. Runtime fills defaults for Logger/Clock/IDs; everything else is intentionally explicit.
type Downloader ¶
Downloader reads a remote path.
type Error ¶
type Error struct {
Code string `json:"code"`
Message string `json:"message"`
Retryable bool `json:"retryable,omitempty"`
RetryAfterMS int `json:"retry_after_ms,omitempty"`
Hint string `json:"hint,omitempty"` // how the agent should fix its input
Detail string `json:"detail,omitempty"` // for developers, never fed to the LLM
}
Error is the stable error shape crossing the capability boundary. Hosts map Code to HTTP status / agent error text without parsing messages. The Code set is a fixed enum — never free text (see docs §5.5.3).
func EvidenceWriteFailed ¶
func InvalidInput ¶
func ScopeDenied ¶
func TargetUnreachable ¶
func ToolMissing ¶
func Unavailable ¶
func UpstreamError ¶
type EventSpec ¶
type EventSpec struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
}
EventSpec declares an event the host may map to notifications/SSE/webhooks.
type Evidence ¶
type Evidence struct {
Kind string `json:"kind"`
Title string `json:"title"`
Target Target `json:"target"`
Request []byte `json:"request,omitempty"`
Response []byte `json:"response,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Evidence is a portable evidence record. The host decides where to store it (traffic store, object store, DB) and returns its stable ID.
type EvidenceRef ¶
type EvidenceRef struct {
ID string `json:"id"`
Kind string `json:"kind"` // http_exchange | file | command_output | scan_log
Size int `json:"size"`
SHA256 string `json:"sha256,omitempty"`
Preview string `json:"preview,omitempty"` // <=200 chars
}
EvidenceRef points at stored evidence. Full bodies never travel in Data; they live in the evidence store and are referenced by ID.
func EvidenceRefs ¶
func EvidenceRefs(outs ...Output) []EvidenceRef
EvidenceRefs collects one reference per distinct evidence id, in the order the outputs were produced, so a result can point at its stored command output.
type EvidenceSink ¶
type ExecOpts ¶
type ExecOpts struct {
Timeout time.Duration `json:"timeout,omitempty"`
Env map[string]string `json:"env,omitempty"`
Dir string `json:"dir,omitempty"`
Stdin []byte `json:"stdin,omitempty"`
Shell string `json:"shell,omitempty"` // sh | bash | cmd | powershell
TTY bool `json:"tty,omitempty"`
MaxOutput int `json:"max_output,omitempty"` // bytes; host default if 0
Background bool `json:"background,omitempty"`
}
ExecOpts tunes one command. Zero values mean "host default".
type Fetcher ¶
Fetcher is the external-data fetch port: rule updates, GitHub search, threat intel and other non-target-scoped downloads. The host still applies proxy, timeout, rate limit and audit policy, but not project target scope.
type Finding ¶
type Finding struct {
Target Target `json:"target"`
Kind string `json:"kind"` // cmdi | sqli | ssti | lfi | ssrf | upload | deser | ...
Fingerprint string `json:"fingerprint,omitempty"`
Confirmed bool `json:"confirmed"`
Payload string `json:"payload,omitempty"`
Evidence []string `json:"evidence,omitempty"`
Source string `json:"source,omitempty"` // nuclei | exploitkit | yuque-template | manual
}
Finding is a normalized vulnerability conclusion. Fingerprint is a normalized target+kind+param+path key used to dedupe the same issue across sources such as nuclei, exploitkit and yuque templates.
type Fingerprint ¶
type Fingerprint struct {
Product string `json:"product"`
Version string `json:"version,omitempty"`
Category string `json:"category,omitempty"`
Source string `json:"source,omitempty"`
Confidence int `json:"confidence,omitempty"`
}
Fingerprint is one detected technology. Kits return it; the host decides whether/how to write it into its asset graph.
type FingerprintProvider ¶
type FingerprintProvider interface {
Fingerprint(ctx context.Context, target Target) ([]Fingerprint, error)
}
FingerprintProvider is implemented by the host or fingerprintkit. verifykit depends only on this interface.
type HTTPDoer ¶
HTTPDoer is the only HTTP client a kit may use. The host injects a gate-aware implementation that enforces scope, rate limits and audit.
type IDGenerator ¶
type Identity ¶
type Identity interface {
Headers(ctx context.Context) (http.Header, error)
Refresh(ctx context.Context) error
Scope() IdentityScope
}
Identity produces the HTTP headers that authenticate a request to a target.
type IdentityScope ¶
type IdentityScope struct {
ProjectID int64 `json:"project_id,omitempty"`
Hosts []string `json:"hosts,omitempty"`
User string `json:"user,omitempty"`
Label string `json:"label,omitempty"`
}
IdentityScope bounds what an identity may be used for.
type IntelItem ¶ added in v0.5.0
type IntelItem struct {
ID string `json:"id,omitempty"`
Source string `json:"source,omitempty"`
UniqueKey string `json:"unique_key"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Severity string `json:"severity,omitempty"`
CVE string `json:"cve,omitempty"`
Disclosure string `json:"disclosure,omitempty"`
Solutions string `json:"solutions,omitempty"`
SourceURL string `json:"source_url,omitempty"`
Tags []string `json:"tags,omitempty"`
References []string `json:"references,omitempty"`
}
IntelItem is one advisory published by a public vulnerability-intel source. The kit owns the protocol; the host owns the schema and the dedup policy, so the only key the kit guarantees is UniqueKey (stable per source).
type IntelQuery ¶ added in v0.5.0
type IntelQuery struct {
Text string `json:"text,omitempty"`
CVE string `json:"cve,omitempty"`
Severity string `json:"severity,omitempty"`
Source string `json:"source,omitempty"`
Limit int `json:"limit,omitempty"`
Cursor string `json:"cursor,omitempty"`
}
IntelQuery filters the host's intel store. Empty fields do not filter.
type IntelSource ¶ added in v0.5.0
type IntelSource interface {
Name() string
Fetch(ctx context.Context, limit int) ([]IntelItem, error)
}
IntelSource is an advisory source the host contributes to the intel kit's poll loop.
It exists because some sources cannot be fetched with a plain HTTP client: they answer every request with an anti-automation page that only a JS runtime can turn into a real URL. Solving that needs a JavaScript engine, which is the wrong dependency for this library — so the host implements the source with whatever it already ships, and the kit polls it alongside its own sources through the same store and dedup path.
Implementations must return normalized items with a stable UniqueKey and a non-empty Source. A failure is reported per source, never as a failed poll.
type IntelStore ¶ added in v0.5.0
type IntelStore interface {
Upsert(ctx context.Context, item IntelItem) (id string, created bool, err error)
Query(ctx context.Context, q IntelQuery) ([]IntelItem, error)
Get(ctx context.Context, id string) (*IntelItem, error)
}
IntelStore is the host-owned persistence for vulnerability intel. Kits never open a database: they hand the host normalized items and the host decides how to store, dedupe and version them.
Upsert is idempotent by UniqueKey. It returns the stored record id and whether it was newly created, so a polling kit can report real deltas instead of a raw insert count.
type JobRef ¶
JobRef references a long-running job. Operations over 30s return StatusPartial plus a JobRef and are polled with job_status.
type Limiter ¶
type Limiter interface {
Acquire(ctx context.Context, key string, spec RateLimitSpec) (release func(), err error)
}
type Manifest ¶
type Manifest struct {
Name string `json:"name"`
Version string `json:"version"`
APIVersion string `json:"api_version"`
Requires []string `json:"requires,omitempty"`
Tools []ToolSpec `json:"tools"`
Settings []SettingSpec `json:"settings,omitempty"`
Events []EventSpec `json:"events,omitempty"`
}
Manifest describes a capability. Requires lists port names the host must provide; Registry.Validate enforces them.
type Meta ¶
type Meta struct {
Tool string `json:"tool"`
Version string `json:"version,omitempty"`
DurationMS int64 `json:"duration_ms"`
Requests int `json:"requests,omitempty"`
Target string `json:"target,omitempty"`
GateTrace []string `json:"gate_trace,omitempty"`
Cached bool `json:"cached,omitempty"`
}
Meta is the fixed envelope metadata. Requests lets an agent see how much of its request budget it just spent; GateTrace makes "why was it slow" visible.
type NextStep ¶
type NextStep struct {
Tool string `json:"tool"`
Reason string `json:"reason"`
Preconditions []string `json:"preconditions,omitempty"`
Risk Risk `json:"risk,omitempty"`
Params json.RawMessage `json:"params,omitempty"`
}
NextStep is a suggested follow-up action. It is data, not a command: the agent (or host policy) decides whether to run it.
func DedupeNext ¶
DedupeNext merges suggestions from several sources into one ordered list, deduping by tool. Convenience for tools that build Next from a finding plus local knowledge.
func SortByRisk ¶
SortByRisk orders steps by descending risk then tool name (stable output for tests and UIs).
type Output ¶
type Output struct {
Command string `json:"command"`
Stdout string `json:"stdout,omitempty"`
Stderr string `json:"stderr,omitempty"`
ExitCode int `json:"exit_code"`
DurationMS int64 `json:"duration_ms"`
Truncated bool `json:"truncated,omitempty"`
// EvidenceID references the stored raw exchange when the host recorded one.
EvidenceID string `json:"evidence_id,omitempty"`
}
Output is the result of one command.
type Page ¶
type Page struct {
Total int `json:"total"`
Cursor string `json:"cursor,omitempty"`
HasMore bool `json:"has_more"`
}
Page describes list pagination. List results exceeding 100 items must paginate and be resumed with Cursor.
func PageWindow ¶
PageWindow resolves a list request into the [start,end) window of a list of total items, plus the Page describing it. Tools whose list can exceed MaxListItems call this so rows are never silently dropped (docs §5.5.4: "列表类结果…超过 100 条必须分页,用 Cursor 续取"). pageSize <= 0 means MaxListItems.
An unusable cursor is an error rather than a silent restart at zero: an agent that paged past the end must be told, not handed the first page again.
type Planner ¶
Planner turns one Finding into candidate next actions. Hosts and agents read the same suggestions. Kits contribute candidates; capkit defines only the contract (see docs §5.3).
func DefaultPlanner ¶
func DefaultPlanner() Planner
DefaultPlanner is the built-in kind->action table. It only suggests the next step for a CONFIRMED finding (an unconfirmed finding yields nothing), and it names tools that the host may or may not have registered.
type PlannerFunc ¶
PlannerFunc adapts a function to Planner.
type ProcessResult ¶
type ProcessRunner ¶
type ProcessRunner interface {
Run(ctx context.Context, spec ProcessSpec) (*ProcessResult, error)
}
ProcessRunner is the only way a kit may spawn a subprocess. The host injects a gate-aware implementation (scope/rate/audit/env policy).
type ProcessSpec ¶
type RateLimitSpec ¶
type RateLimitSpec struct {
PerSecond float64 `json:"per_second,omitempty"`
Burst int `json:"burst,omitempty"`
Concurrency int `json:"concurrency,omitempty"`
}
RateLimitSpec is the declared per-key rate budget for a tool.
func (RateLimitSpec) Normalized ¶
func (s RateLimitSpec) Normalized() RateLimitSpec
Normalized fills safe defaults. PerSecond<=0 means "use host default".
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is the single source of truth for capability declarations. It only validates and stores specs; the runtime instantiates them.
func NewRegistry ¶
func NewRegistry() *Registry
type Response ¶
type Response struct {
Status int `json:"status"`
Headers map[string][]string `json:"headers,omitempty"`
Body []byte `json:"body,omitempty"`
Duration time.Duration `json:"duration"`
FinalURL string `json:"final_url,omitempty"`
RequestText string `json:"request_text,omitempty"`
RespText string `json:"response_text,omitempty"`
}
type Result ¶
type Result struct {
OK bool `json:"ok"`
Status Status `json:"status,omitempty"`
Summary string `json:"summary,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
Findings []Finding `json:"findings,omitempty"`
Evidence []EvidenceRef `json:"evidence,omitempty"`
Next []NextStep `json:"next,omitempty"`
Truncated bool `json:"truncated,omitempty"`
Page *Page `json:"page,omitempty"`
Error *Error `json:"error,omitempty"`
Meta Meta `json:"meta"`
// Text is a legacy human-readable convenience retained for compatibility.
Text string `json:"text,omitempty"`
// EvidenceIDs are the evidence-store IDs of recorded Evidence entries,
// mirrored here for hosts written against earlier versions.
EvidenceIDs []string `json:"evidence_ids,omitempty"`
}
Result is the structured outcome of a tool call. The envelope is the contract agents rely on: Status says what happened, Summary is readable in <=200 chars, Data is a bounded schema-constrained payload, Findings are normalized conclusions, Evidence holds references (never inline bodies), Next lists suggested follow-ups, Meta carries timing/budget trace.
OK stays for wire compatibility with hosts written against earlier versions; it is derived from Status (success/partial => true) and never read for decisions on its own.
func BlockedResult ¶
BlockedResult is a call stopped by a gate (scope/approval/ratelimit).
func DataResult ¶
DataResult is a convenience for structured output.
func FailResult ¶
FailResult wraps an error into a Result, mapping the error code to a Status.
func PartialResult ¶
PartialResult is a partly-completed call carrying structured data and, optionally, a job reference for polling.
func SuccessResult ¶
SuccessResult is a completed call carrying structured data.
func TextResult ¶
TextResult is a convenience for human/agent-readable output.
func (*Result) ClampData ¶
func (r *Result) ClampData()
ClampData enforces the 8KB Data ceiling, replacing oversized payloads with a valid-JSON truncation marker. The real size of the dropped payload is reported in Page.Total so the agent knows how much it did not receive (docs §5.5.4).
func (Result) Normalize ¶
Normalize completes the envelope fields a kit owns on every return path, so a tool cannot satisfy the contract on its happy path and violate it on an error path: it fills an unset Status from Error/OK, keeps OK consistent with Status, stamps Meta.Tool and Meta.Version, and clamps Summary.
A kit calls it once, in its Call dispatcher, rather than at each return. It deliberately does not invent a Summary — a generic "完成" tells an agent nothing, so a missing Summary has to surface as a contract failure.
type Risk ¶
type Risk string
Risk is the declared blast radius of a tool. Hosts use it to decide approval and UI affordances; the runtime also enforces a minimum gate.
type ScopeChecker ¶
ScopeChecker is the authorization boundary. Implementations must fail closed: an unknown/unparseable target is denied.
type Sealer ¶
Sealer protects secrets at rest. Implementations should use AEAD and a host managed key; kits never see plaintext storage details.
type Session ¶
type Session interface {
Exec(ctx context.Context, cmd string, opts ExecOpts) (Output, error)
Info() SessionInfo
Close() error
}
Session is one established, ready-to-use foothold. Implementations must be safe for concurrent Exec calls unless Info reports otherwise.
type SessionInfo ¶
type SessionInfo struct {
ID string `json:"id"`
Kind string `json:"kind"` // ssh | winrm | smb | webshell | cli | c2
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
User string `json:"user,omitempty"`
OS string `json:"os,omitempty"` // linux | windows
Arch string `json:"arch,omitempty"`
Elevated bool `json:"elevated,omitempty"`
Labels []string `json:"labels,omitempty"`
Meta map[string]string `json:"meta,omitempty"`
}
SessionInfo describes the foothold without performing I/O.
type SessionManager ¶
type SessionManager interface {
Open(ctx context.Context, spec SessionSpec) (SessionInfo, error)
Get(id string) (Session, bool)
List() []SessionInfo
Close(id string) error
}
SessionManager is the host-facing port that owns live footholds: it opens sessions through the registered opener for a kind, tracks them by ID, and closes them. Kits (shellkit's session tools, privesc/lat/persist/cleanup) depend only on this port, never on a concrete transport.
type SessionOpener ¶
type SessionOpener interface {
Open(ctx context.Context, spec SessionSpec) (Session, error)
}
SessionOpener opens a new Session from a spec. Adapters (SSH, WinRM, SMB, CLI, WebShell) implement it; hosts register openers and let agents pick one.
type SessionSpec ¶
type SessionSpec struct {
Kind string `json:"kind"` // ssh | winrm | smb | cli | webshell
Host string `json:"host"`
Port int `json:"port,omitempty"`
User string `json:"user,omitempty"`
Secret string `json:"secret,omitempty"` // password or private key
KeyPass string `json:"key_pass,omitempty"`
Domain string `json:"domain,omitempty"`
Protocol string `json:"protocol,omitempty"`
ProxyURL string `json:"proxy,omitempty"`
Timeout time.Duration `json:"timeout,omitempty"`
Labels []string `json:"labels,omitempty"`
Options map[string]string `json:"options,omitempty"`
}
SessionSpec is a transport-neutral request for a foothold. Secret is passed in cleartext here because the host resolves it from the Sealer at the edge; kits never persist it.
type SettingSpec ¶
type SettingSpec struct {
Key string `json:"key"`
Type string `json:"type"` // string | bool | int
Default any `json:"default,omitempty"`
Description string `json:"description,omitempty"`
Secret bool `json:"secret,omitempty"`
}
SettingSpec lets the host render a settings form without kit-specific UI.
type Spec ¶
type Spec struct {
Manifest Manifest
New func(Deps) (Capability, error)
}
Spec is a static capability declaration: manifest + constructor. It holds no instances and no mutable state.
type Status ¶
type Status string
Status is the six-state outcome of a tool call. Six states exist because an agent's reaction differs per state: blocked means change target or request authorization, need_human means suspend for a human, unavailable means report an environment problem. Collapsing these into OK=false makes agents retry blindly and loop against scope checks.
const ( StatusSuccess Status = "success" // completed, no risk StatusPartial Status = "partial" // partly done (e.g. some targets timed out) StatusFailed Status = "failed" // failed, possibly retryable StatusBlocked Status = "blocked" // stopped by a gate: scope / approval / ratelimit StatusNeedHuman Status = "need_human" // high-risk action awaiting human confirmation )
func StatusForError ¶
StatusForError maps a stable error code to the agent-facing status. This is the single place the code->status mapping lives.
type Target ¶
type Target struct {
ProjectID int64 `json:"project_id,omitempty"`
Kind TargetKind `json:"kind"`
URL string `json:"url,omitempty"`
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
IP string `json:"ip,omitempty"`
CIDR string `json:"cidr,omitempty"`
}
Target is a normalized, scope-checkable target. Every tool declares how to extract its targets; the runtime validates them before the kit runs.
func TargetFromString ¶
TargetFromString normalizes a URL, IP, CIDR or hostname.
func TargetFromURL ¶
TargetFromURL normalizes an http(s) URL.
func TargetsFromStrings ¶
TargetsFromStrings normalizes a slice; any invalid target fails the whole set.
type TargetKind ¶
type TargetKind string
TargetKind is the shape of a target.
const ( TargetURL TargetKind = "url" TargetHost TargetKind = "host" TargetDomain TargetKind = "domain" TargetIP TargetKind = "ip" TargetCIDR TargetKind = "cidr" )
type TemplateCatalog ¶
type TemplateCatalog interface {
Search(ctx context.Context, q TemplateQuery) ([]TemplateRef, error)
Get(ctx context.Context, id string) (TemplateRef, bool, error)
}
TemplateCatalog is the engine-neutral template index. It never executes.
type TemplateEngine ¶
type TemplateEngine interface {
Kind() string
Execute(ctx context.Context, refs []TemplateRef, target Target, opts map[string]any) (Result, error)
}
TemplateEngine executes one kind of template (http, nuclei, shell, chain). Execution scheduling/concurrency belongs to the engine implementation.
type TemplateQuery ¶
type TemplateQuery struct {
Text string `json:"text,omitempty"`
Products []string `json:"products,omitempty"`
Fingerprint string `json:"fingerprint,omitempty"`
CVE string `json:"cve,omitempty"`
Tags []string `json:"tags,omitempty"`
Severity []string `json:"severity,omitempty"`
Kind string `json:"kind,omitempty"`
Limit int `json:"limit,omitempty"`
}
TemplateQuery filters a catalog. Empty fields do not filter.
type TemplateRef ¶
type TemplateRef struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Kind string `json:"kind"` // http | nuclei | shell | chain
Engine string `json:"engine,omitempty"` // optional engine hint
Artifact []byte `json:"artifact,omitempty"`
Meta map[string]string `json:"meta,omitempty"`
}
TemplateRef is an engine-neutral reference to one predefined template.
type TokenSnapshot ¶
type TokenSnapshot struct {
AccessToken string `json:"access_token,omitempty"`
ExpiresAt time.Time `json:"expires_at,omitempty"`
IssuedAt time.Time `json:"issued_at,omitempty"`
}
TokenSnapshot captures a token's lifetime so the refresh decision is data, not guesswork.
func (TokenSnapshot) NeedsRefresh ¶
NeedsRefresh reports whether the token should be refreshed at now given a safety skew. A zero ExpiresAt is treated as "no expiry information" and never triggers a refresh on its own.
type ToolSpec ¶
type ToolSpec struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema json.RawMessage `json:"input_schema"`
OutputSchema json.RawMessage `json:"output_schema,omitempty"`
Risk Risk `json:"risk"`
RateLimit RateLimitSpec `json:"rate_limit,omitempty"`
// ExtractTargets is mandatory for tools that act on a target. It is a Go
// function (not serialized); the runtime uses it to enforce scope before
// the kit is called. Tools without a target return nil.
ExtractTargets func(json.RawMessage) ([]Target, error) `json:"-"`
}
ToolSpec is the stable tool contract. InputSchema is JSON Schema; the host exposes it to the agent framework verbatim. OutputSchema describes the shape of this tool's Result.Data so agents know the return before calling.
type TunnelSpec ¶
type TunnelSpec struct {
Kind string `json:"kind"` // local | remote | socks
LocalAddr string `json:"local_addr,omitempty"`
RemoteAddr string `json:"remote_addr"`
Network string `json:"network,omitempty"` // tcp (default) | udp
}
TunnelSpec describes the tunnel a caller wants.