Documentation
¶
Index ¶
- func AllowedDirectories(cfg *config.Config) []string
- func BashAllowedCommands(cfg *config.Config, mode agentdomain.AgentMode) []string
- func BashCommandRejectionHint(cfg *config.Config, command string) string
- func GrantFor(cfg *config.Config, denial *sandboxdomain.DeniedError) sandboxdomain.Allowed
- func IsAnchored(rulePath string) bool
- func IsBashCommandAllowed(cfg *config.Config, command string, mode agentdomain.AgentMode) bool
- func IsUnrestricted(allow []string) bool
- func ValidateRead(cfg *config.Config, path string) error
- func ValidateWrite(cfg *config.Config, path string) error
- type Grants
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AllowedDirectories ¶
AllowedDirectories are the anchored allowed paths, in order, for callers that want somewhere sensible to look.
func BashAllowedCommands ¶
func BashAllowedCommands(cfg *config.Config, mode agentdomain.AgentMode) []string
BashAllowedCommands returns the effective bash allow-list for mode: the shared mode.all baseline unioned with that mode's own bucket. This is the ONE place an AgentMode maps to a tools.bash.mode.<bucket> list: Plan -> plan, AutoAccept -> auto, Standard/AutoWithJudge/unknown -> standard, ReadOnly -> baseline only. The system prompt lists it so the agent knows what runs.
func BashCommandRejectionHint ¶
BashCommandRejectionHint explains why the guard rejected command, or a path outside the sandbox, so the model can correct course instead of retrying. It returns "" when the command is simply not in the allow-list. A nil config skips the sandbox reason.
func GrantFor ¶
func GrantFor(cfg *config.Config, denial *sandboxdomain.DeniedError) sandboxdomain.Allowed
GrantFor is the entry worth asking the user for after a denial: the exact path when a denied entry matched or it sits in a config dir, otherwise the directory around it so the agent can keep working there without a prompt per file.
func IsAnchored ¶
func IsBashCommandAllowed ¶
IsBashCommandAllowed reports whether command is auto-approved in the given agent mode (see BashAllowedCommands for the mode-to-bucket mapping). The model is a pure allow-list with no separate deny list: anything the effective list does not match is denied - in chat mode it falls through to user approval, in headless agent mode it is rejected with a reason (see BashCommandRejectionHint).
- If the effective allow-list contains the sentinel ".*" the mode is UNRESTRICTED: any single command is allowed and the clean-command guard is skipped (full autonomy - this is what mode.auto / headless `infer headless` uses). Tighten mode.auto.allow to a curated list to re-enable the guard.
- Otherwise the clean-command guard runs first and rejects, regardless of the list: command substitution ($(...), backticks, <()/>()), multi-command chains/pipelines (top-level &&, ||, |, ;, &, newline), a surviving file-write redirect (>, >>), a file-writing option (sort -o, tree -o, git --output, uniq's output operand), dangerous find actions (-exec/-delete/...), and printing/publishing an expanded $VAR (echo/printf/gh ... $SECRET, which would leak the value).
- The single clean command is then matched WHOLE against each allow entry (anchored as \A(?:entry)\z), so a bare "gh" allows only "gh" - an entry must opt into arguments explicitly (e.g. "gh issue.*").
- Finally every path the command names must pass the sandbox check the file tools use, so an allow-listed command on a path outside the sandbox asks.
It is the single source of truth consulted by the Bash tool, the approval policy, and agent auto-approval, so all three agree on exactly what runs without prompting.
func IsUnrestricted ¶
IsUnrestricted reports whether the allow-list contains the "allow any command" sentinel, which makes the mode unrestricted (and skips the clean-command guard). ".*", "^.*$", ".+", and a few trivially-equivalent forms qualify.
func ValidateRead ¶
ValidateRead checks that a path and the file it resolves to through symlinks may both be read. Checking the target stops a link inside the sandbox from reaching a file outside it.
Types ¶
type Grants ¶
type Grants struct {
// contains filtered or unexported fields
}
Grants are the entries the user approved after a denial. They extend the configured policy for the rest of the process and never feed the system prompt, which must stay byte-stable within a session.
var Granted Grants
Granted holds the process-wide grants. ponytail: process-wide like the port registry, fold into an injected guard if one process ever runs multiple configs.
func (*Grants) Add ¶
func (g *Grants) Add(entry sandboxdomain.Allowed)
Add grants entry for the rest of the process. Idempotent.
func (*Grants) List ¶
func (g *Grants) List() []sandboxdomain.Allowed
List returns a copy of the granted entries.