scan

package
v1.10.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 10 Imported by: 3

Documentation

Overview

Package scan defines the input/output types and results for safety scans.

Index

Constants

View Source
const QuoteTag = "untrusted_content"

QuoteTag is the element Quote wraps untrusted text in.

View Source
const RiskUnknown = "unknown"

RiskUnknown is the risk class of a tool call that names none. An empty class is never read as a safe one.

Variables

This section is empty.

Functions

func Quote

func Quote(source, text string) string

Quote wraps untrusted text so a model reads it as data, not as instructions:

<untrusted_content source="S">
text
</untrusted_content>

Every tag inside text that a model could read as the wrapper's own, opening or closing, gets a backslash right after its "<" ("<\/untrusted_content", "<\untrusted_content"), so the only closing tag is the last line. The match runs on the folded text (see textnorm.Fold) and so sees through letter case, fullwidth and other compatibility forms, Cyrillic, Greek and other lookalike letters, a "-", a space or no separator in place of the "_", whitespace after the "<" or the "/", and invisible runes and combining marks anywhere inside the tag. Every byte of text is kept; only the backslashes are added. HTML entities and URL encoding ("&lt;/untrusted_content&gt;", "%3C/untrusted_content") are the escaped form of a literal tag, which a model reads as data, and are left alone. S is source in lower case with every rune other than a to z, 0 to 9, '_', '.' and '-' replaced by '_'; an empty source is "unknown".

Types

type Decision

type Decision string

Decision is the final verdict of a safety scan.

const (
	DecisionAllow  Decision = "allow"
	DecisionBlock  Decision = "block"
	DecisionFlag   Decision = "flag"
	DecisionRedact Decision = "redact"
	// DecisionRequireApproval asks a person to approve a tool call. Text
	// scans never return it.
	DecisionRequireApproval Decision = "require_approval"
)

func ActionDecision

func ActionDecision(action string) Decision

ActionDecision returns the decision a finding's action asks for on a text scan: block and throttle block; redact, vault, quote and rewrite redact; flag, alert, warn and escalate flag; log and info allow. Any other action blocks, so an unknown action fails closed. ToolCallActionDecision maps the actions of a tool call.

func Stricter

func Stricter(a, b Decision) Decision

Stricter returns the more restrictive of a and b, in the order allow < flag < redact < require_approval < block. An unknown decision counts as block, so a host combining its own verdict with a scan's fails closed.

func ToolCallActionDecision

func ToolCallActionDecision(action string) Decision

ToolCallActionDecision returns the decision a finding's action asks for on a tool call, which is only ever allow, block or require_approval. Actions that block a text scan block the call. Flag, alert and warn allow it, so the finding reaches the host without sending every flag to a person; log and info allow it too. Escalate, and every action a text scan answers by redacting, quoting or rewriting the text, asks a person, since none of them can change a call. An unknown action blocks, as ActionDecision does.

type Direction

type Direction string

Direction indicates whether content is input (user→agent) or output (agent→user).

const (
	DirectionInput  Direction = "input"
	DirectionOutput Direction = "output"
	// DirectionToolCall marks a scan of a proposed tool call.
	DirectionToolCall Direction = "tool_call"
)

type Finding

type Finding struct {
	ID       id.FindingID   `json:"id"`
	Layer    string         `json:"layer"`    // "instinct", "awareness", "boundary", "values", "judgment", "reflex"
	Source   string         `json:"source"`   // name of the primitive that produced this finding
	Severity string         `json:"severity"` // "info", "warning", "error", "critical"
	Message  string         `json:"message"`
	Score    float64        `json:"score,omitempty"`  // 0.0-1.0 confidence
	Action   string         `json:"action,omitempty"` // recommended action
	Details  map[string]any `json:"details,omitempty"`
}

Finding represents an individual detection from a safety layer.

type Input

type Input struct {
	Text      string         `json:"text"`
	Direction Direction      `json:"direction"`
	Context   map[string]any `json:"context,omitempty"`  // additional context for judgment
	Metadata  map[string]any `json:"metadata,omitempty"` // copied onto the stored scan

	// Profile names the safety profile to evaluate. Empty uses
	// shield.Config.DefaultProfile.
	Profile string `json:"profile,omitempty"`
	// Source says where the text came from, such as "commit_message" or
	// "log_line". Quote puts it on the wrapper of untrusted text.
	Source string `json:"source,omitempty"`
	// Untrusted marks text from outside the operator. Unless the scan
	// blocks, Result.Redacted is then always set to the quoted text, ready
	// to hand to a model.
	Untrusted bool `json:"untrusted,omitempty"`
}

Input represents content to be scanned by the safety engine.

type ListFilter

type ListFilter struct {
	AppID     string
	TenantID  string
	Direction Direction
	Decision  Decision
	Limit     int
	Offset    int
}

ListFilter defines filtering for scan list queries.

type Result

type Result struct {
	shield.Entity
	ID           id.ScanID      `json:"id" bun:",pk"`
	Direction    Direction      `json:"direction" bun:",notnull"`
	Decision     Decision       `json:"decision" bun:",notnull"`
	Blocked      bool           `json:"blocked" bun:",notnull"`
	Findings     []*Finding     `json:"findings" bun:"type:jsonb"`
	Redacted     string         `json:"redacted,omitempty"` // text to use in place of the input; see Input.Untrusted
	PIICount     int            `json:"pii_count,omitempty"`
	ProfileUsed  string         `json:"profile_used,omitempty"`
	PoliciesUsed []string       `json:"policies_used,omitempty" bun:"type:jsonb"`
	TenantID     string         `json:"tenant_id" bun:",notnull"`
	AppID        string         `json:"app_id" bun:",notnull"`
	Duration     time.Duration  `json:"duration"`
	Metadata     map[string]any `json:"metadata,omitempty" bun:"type:jsonb"`
}

Result is the complete output of a safety scan.

func (*Result) HasFindings

func (r *Result) HasFindings() bool

HasFindings returns true if the scan produced any findings.

func (*Result) HasPII

func (r *Result) HasPII() bool

HasPII returns true if the scan detected any PII.

func (*Result) Reason

func (r *Result) Reason() string

Reason returns the message of the first finding whose action produced the final decision, or "" when the scan allowed the text or call. Findings of a tool call map through ToolCallActionDecision.

type Stats

type Stats struct {
	TotalScans   int64            `json:"total_scans"`
	BlockedCount int64            `json:"blocked_count"`
	FlaggedCount int64            `json:"flagged_count"`
	AllowedCount int64            `json:"allowed_count"`
	ByDirection  map[string]int64 `json:"by_direction,omitempty"`
	ByDecision   map[string]int64 `json:"by_decision,omitempty"`
}

Stats holds aggregated scan statistics.

type StatsFilter

type StatsFilter struct {
	AppID    string
	TenantID string
	From     string // ISO 8601 date
	To       string // ISO 8601 date
}

StatsFilter defines filtering for scan statistics queries.

type Store

type Store interface {
	CreateScan(ctx context.Context, result *Result) error
	GetScan(ctx context.Context, scanID id.ScanID) (*Result, error)
	ListScans(ctx context.Context, filter *ListFilter) ([]*Result, error)
	ScanStats(ctx context.Context, filter *StatsFilter) (*Stats, error)
}

Store defines persistence operations for scan results.

type ToolCallInput

type ToolCallInput struct {
	// Tool is the name of the tool. It is required.
	Tool string `json:"tool"`
	// Arguments are the call's JSON arguments, untrusted. Empty and null
	// mean none.
	Arguments json.RawMessage `json:"arguments,omitempty"`
	// RiskClass is the host's own class for the call, such as "read" or
	// "destroy_production". Empty means RiskUnknown.
	RiskClass string `json:"risk_class,omitempty"`
	// Metadata is copied onto the stored scan, and on_context reflexes
	// match its keys.
	Metadata map[string]string `json:"metadata,omitempty"`
	// Profile names the safety profile to evaluate. Empty uses
	// shield.Config.DefaultProfile.
	Profile string `json:"profile,omitempty"`
}

ToolCallInput is a tool call an agent proposes, for engine.ScanToolCall.

Jump to

Keyboard shortcuts

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