bash

package
v0.1.158 Latest Latest
Warning

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

Go to latest
Published: May 2, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package bash is the codefly Bash toolbox — the only sanctioned path for running shell commands across the codefly stack.

Two layers of enforcement, applied in order:

  1. AST-level canonical routing. Every script is parsed with mvdan/sh; each CallExpr's program name is looked up in the policy.CanonicalRegistry. If the binary is owned by a dedicated toolbox (Git, Docker, Nix, …), the script is refused with an error that names the toolbox the caller should use instead. Splitting on `&&`, `||`, `;`, `|`, and subshells happens by construction — every Cmd node is visited. Defeats the canonical "git status && git push" chaining bypass that defeats every existing token-level permission system.

  2. OS sandbox. Even an allowed command runs inside a runners/sandbox wrap with no access to the canonically-denied binaries: bwrap doesn't bind /usr/bin/git, sandbox-exec's profile leaves the binary unreachable. So even if the parser is somehow fooled (a trick we haven't considered), the spawned bash literally cannot find the program to run.

The two layers are independent. Either one alone would be bypassable; together they form the contract.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CanonicalRoutedError

type CanonicalRoutedError struct {
	// Binary is the program name as it appeared in the script (with
	// any leading path stripped).
	Binary string

	// Owner is the toolbox plugin that has claimed this binary, or ""
	// for the built-in fallback (no plugin yet ships the toolbox).
	Owner string

	// Reason is the human-readable explanation suitable for direct
	// surfacing to the agent — actionable, not implementation-leaky.
	Reason string
}

CanonicalRoutedError signals that the script tried to invoke a binary that the canonical registry says belongs to another toolbox. The error is non-fatal at the codefly level — the caller should surface it to the agent as "use the X toolbox instead."

func (*CanonicalRoutedError) Error

func (e *CanonicalRoutedError) Error() string

type Result

type Result struct {
	Stdout   string
	Stderr   string
	ExitCode int
}

Result is the outcome of a non-canonical-refused script.

A canonical refusal returns (nil, *CanonicalRoutedError) — the script never starts. A real exec failure returns (Result with the exit code, nil) — the caller decides whether non-zero is fatal.

type Toolbox

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

Toolbox is the codefly Bash toolbox.

Construct with the canonical registry that captures plugin claims and the sandbox the script will run inside. The sandbox should already be configured (workspace as writable path, network policy, etc.); the bash toolbox layers canonical-routing on top — it does NOT add or weaken sandbox rules.

func New

New returns a Toolbox bound to the given registry and sandbox.

Both arguments are required; nil panics at first Exec, which is preferable to silently running with no enforcement (the failure mode we're explicitly designing against).

func (*Toolbox) Exec

func (t *Toolbox) Exec(ctx context.Context, script string) (*Result, error)

Exec parses, canonical-checks, and runs script under bash inside the configured sandbox.

The script is exactly what `bash -c "<script>"` would receive — callers don't need to escape anything beyond what bash itself expects. Multi-line scripts, pipes, conditionals, subshells all work; the AST walker visits every command node.

Jump to

Keyboard shortcuts

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