Documentation
¶
Overview ¶
Package netpolicy makes senior-dev aware of runs where agent-initiated network access is unavailable, so agents stop wasting cycles attempting it. It governs the builtin web tools (webfetch, websearch) and the environment handed to bash children. The model plane (the model API codeaf serves the run) is deliberately outside its scope: that traffic is senior-dev's own road to a model, not agent-initiated, and a run cannot function without it.
The policy is read from the environment, following the pipeline's existing SENIOR_DEV_* precedent:
SENIOR_DEV_NET=allow current behavior (default when unset) SENIOR_DEV_NET=off agent-initiated egress is unavailable for this run
A value of SENIOR_DEV_NET that parses to neither fails CLOSED to off: a typo in a flag that exists to forbid network access must not silently grant it. The parse problem is preserved on the Policy so callers can surface it; a run refuses to start on it, so a run is never silently degraded by a typo either.
Containment is not this package's job - that belongs to the environment the run executes in (for example a sandbox that only lets the model API through). What this package delivers under off is legibility and economy: the web tools disappear from the model's tool list, in-process HTTP fails instantly with an explicit no-retry policy error instead of a sandbox timeout, and proxy-honoring bash clients (curl, wget, pip, npm, git-over-HTTPS) get a millisecond 403 from a local black-hole listener rather than a DNS or connect stall. Clients that ignore proxy variables simply fail against the outer sandbox instead - slower, but still contained.
Index ¶
Constants ¶
const EnvMode = "SENIOR_DEV_NET"
EnvMode is the environment variable the policy is read from.
Variables ¶
This section is empty.
Functions ¶
func BlackholeAddr ¶
BlackholeAddr returns the address of the per-process black-hole listener, starting or restarting it as needed. Callers invoke this once per shell spawn, so a listener that died costs at most one command of ECONNREFUSED (still fail-closed) before the next spawn restores the legible 403.
func ShellProxyEnv ¶
ShellProxyEnv returns the environment entries that gate proxy-honoring network clients (curl, wget, pip, npm, git-over-HTTPS) in shell children, or nil when the policy leaves bash open. Entries are meant to be appended AFTER os.Environ(): exec dedup is last-entry-wins, so they override any proxy the parent environment carries.
The proxy address is a local black-hole listener that answers every connection with an explicit 403 naming the policy, so a blocked command fails with a legible, non-retryable error instead of a hang. If the listener cannot be (re)established the entries point at 127.0.0.1:1 instead — connection refused, still fail-closed.
Types ¶
type BlockedError ¶
type BlockedError struct {
Host string
// contains filtered or unexported fields
}
BlockedError is the model-facing refusal for one blocked host. It is a distinct type so callers can recover it with errors.As after net/http wraps it (a refusal on a redirect hop comes back from Client.Do inside a *url.Error) and surface the policy text instead of a generic transport failure.
func (*BlockedError) Error ¶
func (err *BlockedError) Error() string
type Policy ¶
type Policy struct {
Mode Mode
// Warning is non-empty when the environment held an unrecognized value
// and the policy failed closed because of it.
Warning string
}
Policy is an immutable snapshot of the egress policy.
func FromLookup ¶
FromLookup parses a policy from an environment accessor, for tests and embedders that do not own the process environment.
func (Policy) EnvironmentNotice ¶
EnvironmentNotice is the per-turn system-prompt paragraph that tells agents up front that the network is unavailable, so the first fetch attempt never happens instead of merely failing fast. Empty under the default policy.
func (Policy) HostError ¶
HostError builds the refusal for one blocked host. The [network-policy] prefix and the no-retry framing follow the [environment-signal] convention in internal/tool/shell_env_signal.go: the point is to stop an agent from burning turns retrying a request that policy, not transient failure, rejected.
func (Policy) Restricted ¶
Restricted reports whether the policy restricts egress at all. Callers on hot paths use it to skip wrapping entirely under the default policy.
func (Policy) Transport ¶
func (p Policy) Transport(base http.RoundTripper) http.RoundTripper
Transport wraps base so every request is refused before it dials while the policy is restricted. Redirect hops re-enter the transport, so each hop is covered. A nil base means http.DefaultTransport, mirroring net/http.