safety

package
v0.6.2 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ShellBinaries = map[string]bool{
	"bash":          true,
	"sh":            true,
	"zsh":           true,
	"ksh":           true,
	"dash":          true,
	"/bin/bash":     true,
	"/usr/bin/bash": true,
	"/bin/sh":       true,
	"/usr/bin/sh":   true,
	"/bin/zsh":      true,
	"/usr/bin/zsh":  true,

	"powershell": true,
	"pwsh":       true,
	"cmd":        true,
}

ShellBinaries are recognized shell binaries that can wrap commands

View Source
var SystemCriticalPaths = []string{
	"/",
	"/bin",
	"/boot",
	"/dev",
	"/etc",
	"/lib",
	"/lib64",
	"/proc",
	"/root",
	"/sbin",
	"/sys",
	"/usr",
	"/var",
}

SystemCriticalPaths are paths that should never be deleted

Functions

func IsShellBinary

func IsShellBinary(binary string) bool

IsShellBinary returns true if the binary is a recognized shell

func IsSystemCritical

func IsSystemCritical(path string) bool

IsSystemCritical returns true if path is a critical system path

func IsWindowsShellBinary added in v0.3.0

func IsWindowsShellBinary(binary string) bool

IsWindowsShellBinary reports whether binary is a recognized shell on Windows, folding case and stripping .exe/.bat/.cmd/.ps1 so `powershell.exe -Command ...` unwraps like `bash -c` does. It is a separate function so tests can exercise Windows matching on any OS.

Types

type Action

type Action int

Action represents the outcome of a rule check

const (
	// Allow permits the command to execute
	Allow Action = iota
	// Block prevents the command from executing
	Block
	// Warn allows execution but logs a warning
	Warn
	// Prompt requires user confirmation before executing
	Prompt
)

func (Action) String

func (a Action) String() string

type AuditConfig

type AuditConfig struct {
	Enabled       bool   `yaml:"enabled"`
	LogDir        string `yaml:"log_dir"`
	RedactSecrets bool   `yaml:"redact_secrets"`
	RetentionDays int    `yaml:"retention_days"`
}

AuditConfig configures audit logging

type AuditEntry

type AuditEntry struct {
	Timestamp  time.Time `json:"timestamp"`
	SessionID  string    `json:"session_id"`
	Command    string    `json:"command"`
	Action     string    `json:"action"`
	Rule       string    `json:"rule"`
	Message    string    `json:"message"`
	WorkingDir string    `json:"working_dir,omitempty"`
}

AuditEntry represents a log entry for blocked commands

type AuditLogger

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

AuditLogger logs blocked commands to JSONL files

func NewAuditLogger

func NewAuditLogger(cfg AuditConfig) *AuditLogger

NewAuditLogger creates a new audit logger

func (*AuditLogger) Close

func (a *AuditLogger) Close() error

Close closes the audit log file

func (*AuditLogger) LogBlocked

func (a *AuditLogger) LogBlocked(cmd string, result *RuleResult, workingDir string) error

LogBlocked logs a blocked command

func (*AuditLogger) SessionID

func (a *AuditLogger) SessionID() string

SessionID returns the current session ID

type Checker

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

Checker is the main orchestrator for safety checks

func NewChecker

func NewChecker(cfg *SafetyConfig) *Checker

NewChecker creates a new safety checker with the given configuration

func (*Checker) Check

func (c *Checker) Check(cmd string, ctx *Context) (*RuleResult, error)

Check validates a command for safety

func (*Checker) Close

func (c *Checker) Close() error

Close cleans up resources (closes audit log)

func (*Checker) Config

func (c *Checker) Config() *SafetyConfig

Config returns the safety configuration

func (*Checker) IsEnabled

func (c *Checker) IsEnabled() bool

IsEnabled returns true if any safety features are enabled

type Context

type Context struct {
	Config       *SafetyConfig
	WorkspaceDir string   // The workspace root directory
	WorkingDir   string   // Effective cwd (may differ from workspace)
	TempDirs     []string // Recognized temp directories
}

Context provides runtime context for safety checks

func NewContext

func NewContext(cfg *SafetyConfig, workspaceDir, workingDir string) *Context

NewContext creates a new safety context

func (*Context) IsTempPath

func (c *Context) IsTempPath(path string) bool

IsTempPath returns true if path is within a recognized temp directory

func (*Context) IsWithinWorkspace

func (c *Context) IsWithinWorkspace(path string) bool

IsWithinWorkspace returns true if path is within workspace

func (*Context) IsWorkspaceRoot

func (c *Context) IsWorkspaceRoot(path string) bool

IsWorkspaceRoot returns true if path equals workspace root

type FindRule

type FindRule struct{}

FindRule checks for dangerous find operations

func (*FindRule) Applies

func (r *FindRule) Applies(parsed *ParsedCommand) bool

Applies returns true if this is a find command

func (*FindRule) Check

func (r *FindRule) Check(parsed *ParsedCommand, ctx *Context) *RuleResult

Check evaluates find commands for dangerous operations

func (*FindRule) Name

func (r *FindRule) Name() string

Name returns the rule identifier

type GitRule

type GitRule struct{}

GitRule checks for dangerous git operations

func (*GitRule) Applies

func (r *GitRule) Applies(parsed *ParsedCommand) bool

Applies returns true if this is a git command

func (*GitRule) Check

func (r *GitRule) Check(parsed *ParsedCommand, ctx *Context) *RuleResult

Check evaluates git commands for dangerous operations

func (*GitRule) Name

func (r *GitRule) Name() string

Name returns the rule identifier

type GitSafetyConfig

type GitSafetyConfig struct {
	BlockPush             bool `yaml:"block_push"`
	BlockHardReset        bool `yaml:"block_hard_reset"`
	BlockCheckoutDiscard  bool `yaml:"block_checkout_discard"`
	BlockStashDrop        bool `yaml:"block_stash_drop"`
	BlockCleanForce       bool `yaml:"block_clean_force"`
	WarnBranchForceDelete bool `yaml:"warn_branch_force_delete"`
}

GitSafetyConfig configures git operation safety

type InterpreterConfig

type InterpreterConfig struct {
	BlockOneLiners bool     `yaml:"block_one_liners"`
	Allowed        []string `yaml:"allowed"`
}

InterpreterConfig configures interpreter one-liner blocking

type ParsedCommand

type ParsedCommand struct {
	Binary     string            // The executable (e.g., "git", "rm")
	Subcommand string            // First positional arg if applicable (e.g., "push", "reset")
	Flags      map[string]bool   // Present flags (e.g., "-rf" -> {"r": true, "f": true})
	FlagArgs   map[string]string // Flags with values (e.g., "-c" -> "inner command")
	Args       []string          // Positional arguments
	Raw        string            // Original command string
	Pipes      []*ParsedCommand  // Commands after | (for pipeline analysis)
}

ParsedCommand represents a parsed shell command

func ParseCommand

func ParseCommand(cmd string) (*ParsedCommand, error)

ParseCommand parses a shell command string into structured components

func UnwrapAll

func UnwrapAll(parsed *ParsedCommand, maxDepth int) ([]*ParsedCommand, error)

UnwrapAll unwraps the main command and all pipe segments

func UnwrapShellCommand

func UnwrapShellCommand(parsed *ParsedCommand, maxDepth int) ([]*ParsedCommand, error)

UnwrapShellCommand recursively unwraps shell invocations like: - bash -c 'dangerous command' - sh -c "dangerous command" - env bash -c 'command' Returns a list of inner commands that need to be checked

func (*ParsedCommand) ArgsAfterDoubleDash

func (p *ParsedCommand) ArgsAfterDoubleDash() []string

ArgsAfterDoubleDash returns arguments after "--"

func (*ParsedCommand) GetFlagArg

func (p *ParsedCommand) GetFlagArg(flag string) (string, bool)

GetFlagArg returns the argument for a flag, if any

func (*ParsedCommand) HasAnyDestructiveRmFlags

func (p *ParsedCommand) HasAnyDestructiveRmFlags() (recursive, force bool)

HasAnyDestructiveRmFlags checks for recursive and force flags

func (*ParsedCommand) HasDoubleDash

func (p *ParsedCommand) HasDoubleDash() bool

HasDoubleDash returns true if "--" appears in the arguments (often used to separate flags from paths, like git checkout -- file)

func (*ParsedCommand) HasFlag

func (p *ParsedCommand) HasFlag(flags ...string) bool

HasFlag checks if a flag is present (supports both short and long forms)

type Redactor

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

Redactor removes sensitive data from strings

func NewRedactor

func NewRedactor() *Redactor

NewRedactor creates a new secret redactor with default patterns

func (*Redactor) AddPattern

func (r *Redactor) AddPattern(pattern string) error

AddPattern adds a custom pattern to redact

func (*Redactor) Redact

func (r *Redactor) Redact(input string) string

Redact replaces sensitive data in the input string with [REDACTED]

type Registry

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

Registry holds all registered rules

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new empty rule registry

func (*Registry) CheckAll

func (r *Registry) CheckAll(parsed *ParsedCommand, ctx *Context) *RuleResult

CheckAll runs all applicable rules, returning on first blocking result Rules are checked in registration order; first Block/Warn/Prompt wins

func (*Registry) Register

func (r *Registry) Register(rule Rule)

Register adds a rule to the registry

func (*Registry) Rules

func (r *Registry) Rules() []Rule

Rules returns all registered rules (for testing/debugging)

type RmRule

type RmRule struct{}

RmRule checks for dangerous rm operations

func (*RmRule) Applies

func (r *RmRule) Applies(parsed *ParsedCommand) bool

Applies returns true if this is an rm command

func (*RmRule) Check

func (r *RmRule) Check(parsed *ParsedCommand, ctx *Context) *RuleResult

Check evaluates rm commands for dangerous operations

func (*RmRule) Name

func (r *RmRule) Name() string

Name returns the rule identifier

type RmSafetyConfig

type RmSafetyConfig struct {
	AllowInTemp         bool `yaml:"allow_in_temp"`
	AllowInWorkspaceCwd bool `yaml:"allow_in_workspace_cwd"`
	BlockWorkspaceRoot  bool `yaml:"block_workspace_root"`
}

RmSafetyConfig configures rm command safety

type Rule

type Rule interface {
	// Name returns the rule identifier (for logging/audit)
	Name() string

	// Applies returns true if this rule should check the given command
	Applies(parsed *ParsedCommand) bool

	// Check evaluates the command against this rule
	Check(parsed *ParsedCommand, ctx *Context) *RuleResult
}

Rule is the interface for all safety rules

type RuleResult

type RuleResult struct {
	Action  Action   // The action to take
	Rule    string   // Name of rule that triggered (for logging)
	Message string   // Human-readable explanation
	Paths   []string // Affected paths (for path-based prompting)
}

RuleResult encapsulates the outcome of applying safety rules

func AllowResult

func AllowResult() *RuleResult

AllowResult returns a result that permits execution

func BlockResult

func BlockResult(rule, message string) *RuleResult

BlockResult returns a result that prevents execution

func PromptResult

func PromptResult(rule, message string, paths []string) *RuleResult

PromptResult returns a result that requires user confirmation

func WarnResult

func WarnResult(rule, message string) *RuleResult

WarnResult returns a result that permits execution with a warning

func (*RuleResult) IsBlocking

func (r *RuleResult) IsBlocking() bool

IsBlocking returns true if the result prevents command execution

func (*RuleResult) RequiresInteraction

func (r *RuleResult) RequiresInteraction() bool

RequiresInteraction returns true if user interaction is needed

type SafetyConfig

type SafetyConfig struct {
	StrictMode   bool              `yaml:"strict_mode"`   // Fail-closed on parse errors
	ParanoidMode bool              `yaml:"paranoid_mode"` // Aggressive restrictions
	Audit        AuditConfig       `yaml:"audit"`
	Git          GitSafetyConfig   `yaml:"git"`
	Rm           RmSafetyConfig    `yaml:"rm"`
	Interpreters InterpreterConfig `yaml:"interpreters"`
}

SafetyConfig holds safety mode configuration

type XargsRule

type XargsRule struct{}

XargsRule checks for dangerous xargs/parallel operations

func (*XargsRule) Applies

func (r *XargsRule) Applies(parsed *ParsedCommand) bool

Applies returns true if this is an xargs or parallel command Also applies if a pipeline contains xargs/parallel

func (*XargsRule) Check

func (r *XargsRule) Check(parsed *ParsedCommand, ctx *Context) *RuleResult

Check evaluates xargs/parallel commands for dangerous operations

func (*XargsRule) Name

func (r *XargsRule) Name() string

Name returns the rule identifier

Jump to

Keyboard shortcuts

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