env

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 24, 2026 License: MIT Imports: 4 Imported by: 0

README

runtime/env/

Compose the KEY=VALUE slice handed to exec.Cmd.Env for an agent provider subprocess.

What it does

c := env.NewComposer()
out := c.Compose(map[string]string{
    "PATH":              "/usr/bin",
    "ANTHROPIC_API_KEY": "operator-leak", // host shell var; will be filtered
}, agent.Spec{Env: map[string]string{
    "ANTHROPIC_API_KEY":      "runner-resolved", // override is allowed
    "AGENTFACTORY_SESSION_ID": "sess-123",
}})
// out: ["AGENTFACTORY_SESSION_ID=sess-123",
//       "ANTHROPIC_API_KEY=runner-resolved",
//       "PATH=/usr/bin"]

AGENT_ENV_BLOCKLIST (verbatim port)

ANTHROPIC_API_KEY
ANTHROPIC_AUTH_TOKEN
ANTHROPIC_BASE_URL
OPENCLAW_GATEWAY_TOKEN

Source: ../../../agentfactory/packages/core/src/orchestrator/orchestrator.ts (and agent-spawner.ts). The legacy TS keeps the same 4-element list verbatim across both files; TestAgentEnvBlocklistMatchesLegacyTS asserts the Go port stays in sync.

The blocklist applies only to the base map passed to Compose. Spec.Env is runner-set and intentionally trusted — that is how the daemon resolves ANTHROPIC_API_KEY from its credential store and injects it for the session.

Heuristic helpers

  • IsBlocked(key string) bool — exact match against the effective blocklist.
  • LooksSensitive(key string) bool — soft heuristic (substring match against TOKEN/SECRET/PASSWORD/PASSWD/PRIVATE_KEY/API_KEY). Not a security boundary; useful for "operator probably did not mean to set this" log warnings.

Tests

composer_test.go covers: precedence, blocklist filtering, spec-overrides-blocked, custom blocklist, empty-non-nil bypasses filtering, deterministic key order, nil receiver fallback, sentinel test pinning blocklist contents.

Documentation

Overview

Package env composes process environments for agent provider subprocesses.

The runner hands every provider a base environment merged from (a) the host process env, (b) provider-resolved secrets (e.g. ANTHROPIC_API_KEY from the daemon credential store), and (c) the per-session Spec.Env map. Before merging, sensitive variables in AGENT_ENV_BLOCKLIST are stripped from the host pass-through so an operator's interactive shell credential cannot leak into the agent's subprocess.

Source: ../agentfactory/packages/core/src/orchestrator/orchestrator.ts (AGENT_ENV_BLOCKLIST) — port verbatim per F.1.1 §1.

Index

Constants

This section is empty.

Variables

View Source
var AgentEnvBlocklist = []string{
	"ANTHROPIC_API_KEY",
	"ANTHROPIC_AUTH_TOKEN",
	"ANTHROPIC_BASE_URL",
	"OPENCLAW_GATEWAY_TOKEN",
}

AgentEnvBlocklist is the set of environment variable names that must never propagate from the daemon's host environment into an agent provider subprocess.

The list mirrors AGENT_ENV_BLOCKLIST in ../agentfactory/packages/core/src/orchestrator/orchestrator.ts and agent-spawner.ts verbatim. It captures the sensitive Anthropic auth surface plus the OpenClaw gateway token; provider implementations inject their credential of choice through Spec.Env (which is NOT blocked — see Composer.Compose).

When the legacy TS adds a new entry, port it here and update the inline comment in package env's README.

Functions

func LooksSensitive

func LooksSensitive(key string) bool

LooksSensitive reports whether key matches a heuristic pattern for a likely-sensitive env var (token, secret, key, password). The runner uses this to emit a soft warning when a Spec.Env entry may have been set by mistake. It is not a security boundary — the blocklist is.

Types

type Composer

type Composer struct {
	// Blocklist overrides AgentEnvBlocklist for this Composer. A nil
	// or empty slice falls back to AgentEnvBlocklist; pass an empty
	// non-nil slice ([]string{}) to disable blocklisting entirely.
	Blocklist []string
}

Composer builds the KEY=VALUE slice handed to exec.Cmd.Env for an agent provider subprocess.

A nil Composer is valid: zero-value methods use AgentEnvBlocklist. Tests can override Blocklist to validate filtering behavior without touching the package-level constant.

func NewComposer

func NewComposer() *Composer

NewComposer returns a Composer using the package-level AgentEnvBlocklist. Equivalent to &Composer{}.

func (*Composer) Compose

func (c *Composer) Compose(base map[string]string, spec agent.Spec) []string

Compose returns a deterministic []string in KEY=VALUE form suitable for exec.Cmd.Env.

Precedence (lowest to highest, last write wins):

  1. base — typically os.Environ() parsed into a map. Entries whose key is in the blocklist are dropped before merge so a daemon operator's ANTHROPIC_API_KEY does not bleed into the agent subprocess.
  2. spec.Env — the per-session env map carried on agent.Spec. NOT subject to the blocklist (the runner sets these intentionally).

Within each layer the merge is map-iteration-order-stable: keys are sorted lexicographically to keep golden tests reproducible.

Empty values (V == "") are preserved — exec.Cmd treats KEY= as "set to empty", which differs from "unset". The runner uses this to override an inherited host variable.

Returns the merged []string. The caller can append additional runner-internal entries before handing it to exec.Cmd.Env.

func (*Composer) IsBlocked

func (c *Composer) IsBlocked(key string) bool

IsBlocked reports whether key is in the effective blocklist for this Composer. Useful for callers that want to log a warning when an operator-supplied env attempted to set a sensitive variable.

Jump to

Keyboard shortcuts

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