Help us shape the future of Go! Take the 2026 Go Developer Survey

lockdown

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package lockdown holds the run-level taint state of the opt-in untrusted-content lockdown (untrusted_content.enabled / --lockdown, issue #171). A run becomes tainted when content from an untrusted source enters the model's context (a web_fetch or MCP result, a review diff, an --untrusted-task task). From then until the run ends the outbound channels tinyagent controls are refused: commands, web_fetch outside its lockdown allowlist, and MCP tools.

Taint is decided by source, never by content, and records hold only source names, tool names, ids, steps and hosts: no fetched content, MCP results, URLs, query strings or environment values.

Index

Constants

View Source
const (
	// CommandsRefused: commands are refused after taint.
	CommandsRefused = "refused"
	// CommandsSandboxed: commands keep running after taint, confined by the
	// sandbox.
	CommandsSandboxed = "sandboxed"

	// CommandNetworkDenied: confined commands have no network.
	CommandNetworkDenied = "denied"
	// CommandNetworkProxy: confined commands reach the network only through
	// the allowlist proxy, narrowed at the first taint.
	CommandNetworkProxy = "proxy"
)

Command policy values reported in run.started and OTel attributes.

View Source
const (
	SourceWebFetch      = "web_fetch"
	SourceMCP           = "mcp"
	SourceReview        = "review"
	SourceUntrustedTask = "untrusted_task"
	// SourceResume marks a resumed checkpoint whose history already holds
	// untrusted content.
	SourceResume = "resume"
)

Taint sources.

View Source
const (
	ChannelCommand  = "command"
	ChannelWebFetch = "web_fetch"
	ChannelMCP      = "mcp"
)

Channels lockdown restricts after taint.

View Source
const CommandEnvironmentContainer = "container"

CommandEnvironmentContainer is the environment value reported in run.started for commands confined in the container environment.

View Source
const CommandNetworkDirect = "direct"

CommandNetworkDirect is run.started's lockdown.commands.network_before_taint when sandboxed commands have direct network (sandbox_network) until the first taint takes it away.

View Source
const Notice = "[tinyagent: untrusted content received; commands, web_fetch and MCP tools are restricted for the rest of this run]"

Notice is appended once per run to the tool result that first taints it.

View Source
const SourceACPClientMCP = "acp_client_mcp"

SourceACPClientMCP is a result from an MCP server an ACP client supplied to the session (see SetACPClientMCPServers).

Variables

ConfigurableSources are the taint sources untrusted_content.sources can choose from, in the order they are described. --untrusted-task and a resumed untrusted checkpoint are not configurable: asking for them is explicit, and a tainted history stays tainted.

Functions

func ParseSources

func ParseSources(list []string) (map[string]bool, error)

ParseSources checks an untrusted_content.sources list and returns the enabled set. A nil list (the key is absent) enables every configurable source and returns nil. An explicit empty list, an unknown name and a duplicate are errors, so a typo can't silently turn a source off.

func RefusalMessage

func RefusalMessage(tool, channel string, first Source, host string) string

RefusalMessage is the tool error the model sees for a refused call.

func URLHostPort

func URLHostPort(raw string) (host string, port int, ok bool)

URLHostPort returns the host and port a web_fetch URL would connect to first. ok is false for a URL web_fetch could not fetch; lockdown refuses those after taint rather than guessing.

Types

type Denial

type Denial struct {
	Channel    string `json:"channel"`
	Tool       string `json:"tool"`
	ToolCallID string `json:"tool_call_id"`
	Step       int    `json:"step"`
	Host       string `json:"host,omitempty"`
}

Denial is one call refused by lockdown.

func (Denial) Fields

func (d Denial) Fields() map[string]any

Fields returns the lockdown.denied event fields.

type MCPServerPolicy

type MCPServerPolicy struct {
	Alias string
	// Trusted is untrusted: false: the server's results don't taint the
	// run. The default is false, so results taint.
	Trusted bool
	// LockdownAllowed is lockdown_allowed: true: the server's tools stay
	// callable after taint. The default is false, so they are refused.
	LockdownAllowed bool
}

MCPServerPolicy is one configured MCP server's lockdown settings (mcp_servers[].untrusted and mcp_servers[].lockdown_allowed).

type Source

type Source struct {
	Source     string `json:"source"`
	Step       int    `json:"step"`
	ToolCallID string `json:"tool_call_id,omitempty"`
	Tool       string `json:"tool,omitempty"`
	// Host is the web_fetch URL host (no scheme, path or query).
	Host string `json:"host,omitempty"`
	// Resumed marks a source restored from a checkpoint: it tainted an
	// earlier invocation of the run.
	Resumed bool `json:"resumed,omitempty"`
}

Source is one recorded taint: what brought untrusted content into context and where.

func (Source) Fields

func (s Source) Fields() map[string]any

Fields returns the taint event fields.

type State

type State struct {
	// contains filtered or unexported fields
}

State is one run's lockdown state. It is shared by the run's agent and its children (workers, delegates), so it is safe for concurrent use. A nil *State means lockdown is off: it is never tainted and refuses nothing.

func New

func New(webFetchAllowed []string) (*State, error)

New returns an untainted state whose web_fetch lockdown allowlist is webFetchAllowed, in the sandbox_allowed_domains syntax.

func (*State) ACPClientMCPAliases

func (s *State) ACPClientMCPAliases() []string

ACPClientMCPAliases returns the client-supplied server aliases, sorted.

func (*State) CommandDomains

func (s *State) CommandDomains() []string

CommandDomains returns untrusted_content.lockdown.allowed_domains.

func (*State) CommandsConfined

func (s *State) CommandsConfined() bool

CommandsConfined reports whether commands keep running after taint.

func (*State) CommandsInfo

func (s *State) CommandsInfo() map[string]any

CommandsInfo returns the after-taint command policy for run.started: policy (refused or sandboxed), and for sandboxed commands their network (denied or proxy). Proxied commands also list allowed_domains, the untrusted_content.lockdown.allowed_domains patterns the proxy is narrowed to at taint ([] when none). Host patterns only, never content.

func (*State) ConfineCommands

func (s *State) ConfineCommands(proxied bool, narrow func([]string))

ConfineCommands marks the run's commands as confined, so they keep running after taint instead of being refused. proxied says they reach the network only through the allowlist proxy; narrow, which may be nil when they have no network, restricts that proxy to CommandDomains. narrow runs once: at the first taint, or right away when the run is already tainted. Call it only when every command the run can start (workers included) goes through that sandbox, and before the run starts.

func (*State) ContainerProxy

func (s *State) ContainerProxy() bool

ContainerProxy reports untrusted_content.lockdown.container_proxy.

func (*State) Denials

func (s *State) Denials() []Denial

Denials returns the refused calls in order.

func (*State) Deny

func (s *State) Deny(d Denial)

Deny records a refused call.

func (*State) Describe

func (s *State) Describe() string

Describe is the startup line printed when lockdown is enabled.

func (*State) EnabledSources

func (s *State) EnabledSources() []string

EnabledSources lists the configurable sources that taint the run, in ConfigurableSources order.

func (*State) First

func (s *State) First() (src Source, ok bool)

First returns the run's first taint source; ok is false when untainted.

func (*State) Info

func (s *State) Info() map[string]any

Info returns the lockdown config, the after-taint command policy (see CommandsInfo) and the current taint state for run.started: names and host patterns only, never content.

func (*State) MCPAliases

func (s *State) MCPAliases() []string

MCPAliases returns the aliases of the servers SetMCPServers and SetACPClientMCPServers recorded, in sorted order.

func (*State) MCPCallAllowed

func (s *State) MCPCallAllowed(aliases []string) bool

MCPCallAllowed reports whether a call that may reach any of aliases is still allowed after taint. It fails closed: an empty list or an unknown alias is refused, and every server must be lockdown_allowed: true.

func (*State) MCPCallTaints

func (s *State) MCPCallTaints(aliases []string) bool

MCPCallTaints reports whether a result from a call that may have reached any of aliases taints the run. It fails closed: an empty list or an unknown alias taints, and so does any server not marked untrusted: false.

func (*State) MCPTaintSource

func (s *State) MCPTaintSource(aliases []string) (string, bool)

MCPTaintSource returns the taint source of a result from a call that may have reached any of aliases, and whether it taints the run. A client-supplied server taints as acp_client_mcp, any other server not marked untrusted: false as mcp; the first such server whose source is enabled in untrusted_content.sources decides. It fails closed: a call that can't be tied to a server (empty aliases) taints as mcp, or as acp_client_mcp when mcp is turned off and the client supplied servers.

func (*State) RefuseCommands

func (s *State) RefuseCommands()

RefuseCommands withdraws ConfineCommands: commands are refused after taint from now on. It is the fail-closed path when the narrow hook can't restrict their network.

func (*State) Restore

func (s *State) Restore(sources []Source, denials []Denial)

Restore records the taint sources and denials of a resumed checkpoint ahead of any recorded so far, so a run that was tainted stays tainted with its original sources. The sources are marked Resumed, and the first-taint notice counts as given: the conversation already carries it. Call it before the run starts.

func (*State) SetACPClientMCPServers

func (s *State) SetACPClientMCPServers(aliases []string)

SetACPClientMCPServers marks the run as an ACP session and records the aliases of the MCP servers its client supplied. Results from those servers taint as acp_client_mcp rather than mcp, so untrusted_content.sources can choose them separately. Client servers have no mcp_servers entry, so they keep the strict defaults: their results always taint (when acp_client_mcp is a source) and their tools are refused after taint. Call it before the session's first turn.

func (*State) SetCommandAllowedDomains

func (s *State) SetCommandAllowedDomains(domains []string) error

SetCommandAllowedDomains records untrusted_content.lockdown.allowed_domains, the hosts sandboxed commands may still reach through the allowlist proxy after taint (sandbox_allowed_domains syntax; a bare * is rejected). Call it before the run starts.

func (*State) SetCommandsDirectUntilTaint

func (s *State) SetCommandsDirectUntilTaint()

SetCommandsDirectUntilTaint records that the confined commands (ConfineCommands) have direct network until the first taint, when the narrow hook takes it away: a sandbox_network sandbox. Background processes started before taint keep their direct network, so StopsProcessesAtTaint reports true. Call it after ConfineCommands and before the run starts.

func (*State) SetCommandsInContainer

func (s *State) SetCommandsInContainer(removedAtTaint bool)

SetCommandsInContainer records that the confined commands (ConfineCommands) run in the container environment. removedAtTaint says the container has network until the first taint, when the narrow hook disconnects it; otherwise it never had any (--network none). Processes running in the container lose their network with it, so background processes are left running. Call it after ConfineCommands and before the run starts.

func (*State) SetContainerProxy

func (s *State) SetContainerProxy(on bool)

SetContainerProxy records untrusted_content.lockdown.container_proxy: in the container environment, commands reach CommandDomains after taint through a lockdown proxy on an internal runtime network instead of having no network. Call it before the run starts.

func (*State) SetMCPServers

func (s *State) SetMCPServers(servers []MCPServerPolicy)

SetMCPServers records the configured MCP servers' lockdown settings. Call it before the run starts. A server that isn't listed, including one an ACP client supplies, keeps the defaults: its results taint and its tools are refused after taint.

func (*State) SetSources

func (s *State) SetSources(list []string) error

SetSources limits the configurable sources that taint the run to list, in the untrusted_content.sources syntax (nil means all of them). Call it before the run starts.

func (*State) Sources

func (s *State) Sources() []Source

Sources returns the recorded taint sources in order.

func (*State) StopsProcessesAtTaint

func (s *State) StopsProcessesAtTaint() bool

StopsProcessesAtTaint reports whether the first taint must stop the running background processes because lockdown can't restrict their network: commands aren't confined, or had direct network until taint.

func (*State) Taint

func (s *State) Taint(src Source) (added, first bool)

Taint records src. added is false when the same source, tool and host were already recorded, or when src's source is turned off in untrusted_content.sources. first is true only for the run's first taint, the one whose tool result carries Notice; a taint recorded before the run starts (task, review, resume) has no result and uses it up, since every refusal explains itself anyway.

func (*State) Tainted

func (s *State) Tainted() bool

Tainted reports whether untrusted content has entered the run's context.

func (*State) TaintsFrom

func (s *State) TaintsFrom(source string) bool

TaintsFrom reports whether a result from source taints the run. It is always false when lockdown is off, and always true for the sources that aren't configurable (an untrusted task, a resumed untrusted checkpoint).

func (*State) WebFetchAllowed

func (s *State) WebFetchAllowed(host string, port int) bool

WebFetchAllowed reports whether web_fetch may still read host:port: always before taint, and after taint only when it matches the lockdown allowlist.

func (*State) WebFetchDomains

func (s *State) WebFetchDomains() []string

WebFetchDomains returns the configured web_fetch lockdown allowlist.

func (*State) WebFetchGate

func (s *State) WebFetchGate(host string, port int) error

WebFetchGate is the per-hop check web_fetch runs before every request, redirects included: after taint, a host outside the lockdown allowlist is refused before any connection.

Jump to

Keyboard shortcuts

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