Skip to content
be-wise-be-kindPublic

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

SafeShell

License: MIT Python 3.11+

Command-line safety layer for AI coding assistants.

SafeShell intercepts shell commands from AI tools like Claude Code, evaluates them against configurable rules, and enforces decisions before execution. Protect your system from accidental rm -rf, prevent exposure of sensitive files, and maintain control over what AI assistants can do on your machine.

Why SafeShell?

AI coding assistants are powerful but operate with your shell permissions. Without guardrails:

  • A misunderstood request could delete important files
  • Sensitive data (SSH keys, credentials) could be exposed
  • Destructive git operations could corrupt repositories
  • System configurations could be modified unexpectedly

SafeShell provides:

  • Rule-Based Protection: YAML-configured rules match commands by pattern, context, or bash conditions
  • Approval Workflow: Require human approval for risky operations
  • Real-Time Monitoring: Watch all commands in a terminal UI
  • Context Awareness: Different rules for AI tools vs human operators

Architecture

SafeShell uses a hybrid shim + daemon architecture for comprehensive command interception:

flowchart TB
    subgraph Sources["Command Sources"]
        Human["Human Terminal"]
        Claude["Claude Code"]
        Warp["Warp AI Agent"]
        Scripts["Shell Scripts"]
    end

    subgraph Install["Installation (choose one)"]
        UV["uv tool install (recommended)"]
        Pipx["pipx install"]
        UVDev["uv sync (dev)"]
    end

    subgraph Interception["Interception Layer"]
        Shims["Command Shims<br/>~/.safeshell/shims/"]
        Wrapper["Shell Wrapper<br/>safeshell-wrapper"]
        Hook["Claude Code Hook<br/>~/.safeshell/hooks/"]
    end

    subgraph Core["SafeShell Daemon"]
        Server["Unix Socket Server"]
        Rules["Rules Engine"]
        Approval["Approval Manager"]
        Memory["Session Memory"]
    end

    subgraph Actions["Enforcement"]
        Allow["✓ Allow"]
        Deny["✗ Deny"]
        Require["? Require Approval"]
    end

    Monitor["Monitor TUI<br/>safeshell monitor"]

    UV --> Wrapper
    Pipx --> Wrapper
    UVDev --> Wrapper

    Human --> Shims
    Claude --> Hook
    Claude --> Wrapper
    Warp --> Shims
    Warp --> Wrapper
    Scripts --> Shims

    Shims --> Server
    Wrapper --> Server
    Hook --> Server

    Server --> Rules
    Rules --> Allow
    Rules --> Deny
    Rules --> Approval
    Approval --> Memory
    Memory --> Require

    Server -.-> Monitor
    Monitor -.->|approve/deny| Approval
Loading

Component Overview

Component Purpose
Command Shims Symlinks in ~/.safeshell/shims/ that intercept external commands (git, rm, docker, etc.)
Shell Function Overrides Override shell builtins (cd, source, eval) via init.bash
Shell Wrapper AI tools set SHELL=safeshell-wrapper to intercept all commands
Daemon Unix socket server that loads rules, evaluates commands, and manages approvals
Monitor TUI Real-time terminal UI for command visibility and approval workflow

Features

Command Interception

  • Shim-based interception for external commands (git, rm, docker, etc.)
  • Shell function overrides for builtins (cd, source, eval)
  • AI tool hooks for Claude Code integration
  • Transparent pass-through for allowed commands

Rules Engine

  • YAML configuration with global and per-repository rules
  • Bash conditions for complex matching logic
  • Context-aware filtering with ai_only and human_only rules
  • Action types: allow, deny, require_approval, redirect

Monitor TUI

  • Real-time event stream of all intercepted commands
  • Approval workflow with approve/deny buttons
  • Debug mode for rule evaluation visibility
  • Keyboard navigation for efficient operation

Integrations

  • Claude Code via PreToolUse hook
  • Shell integration via init.bash sourcing

Quick Start

1. Install SafeShell

# From source (recommended during development)
git clone https://github.com/be-wise-be-kind/safeshell.git
cd safeshell
uv sync

2. Initialize Configuration

safeshell init

This creates:

  • ~/.safeshell/config.yaml - Global configuration
  • ~/.safeshell/rules.yaml - Global rules
  • ~/.safeshell/shims/ - Command shims

3. Start the Daemon

safeshell daemon start

4. Integrate with Your Shell

Add to your ~/.bashrc or ~/.zshrc:

source ~/.safeshell/init.bash

5. Set Up Claude Code Hook

To intercept commands from Claude Code, add the following to ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.safeshell/hooks/claude_code_hook.py"
          }
        ]
      }
    ]
  }
}

Note: If you installed SafeShell from source with Poetry, point the hook to the source file instead: "/path/to/safeshell/src/safeshell/hooks/claude_code_hook.py"

After editing settings.json, restart Claude Code for the hook to take effect.

6. Test the Setup

# Check a command without executing
safeshell check "rm -rf /"

# Start the monitor to see real-time events
safeshell monitor

Installation

Prerequisites

  • Python 3.11 or higher

Platform Notes

GNOME on Wayland

GNOME's default focus-stealing prevention blocks SafeShell's approval window from appearing in front of other windows. To allow the approval dialog to grab focus when a command needs approval:

gsettings set org.gnome.desktop.wm.preferences focus-new-windows 'smart'

This changes the setting from strict (blocks all focus stealing) to smart (allows new windows to take focus when appropriate).

Option 1: uv tool install (Recommended)

# Install system-wide into an isolated environment
uv tool install safeshell
safeshell init

Option 2: pipx

pipx install safeshell
safeshell init

Option 3: uv (Development)

git clone https://github.com/be-wise-be-kind/safeshell.git
cd safeshell
uv sync

# Run tests
uv run pytest

# Run linting
uv run ruff check src/

Hook Executable Discovery

The Claude Code hook automatically finds safeshell-wrapper in this order:

  1. PATH - Searches all directories in $PATH
  2. Common locations - ~/.local/bin/safeshell-wrapper, /usr/local/bin/safeshell-wrapper
  3. pyenv versions - Direct lookup in ~/.pyenv/versions/*/bin/ (handles version mismatch)
  4. uv - Falls back to uv run for development

Configuration

SafeShell uses YAML configuration files at two levels:

Global Configuration

~/.safeshell/config.yaml:

socket_path: /tmp/safeshell.sock
log_level: INFO
approval_timeout_seconds: 300
condition_timeout_ms: 100

Rules Configuration

~/.safeshell/rules.yaml (global) and .safeshell/rules.yaml (per-repo):

rules:
  - name: block-rm-rf
    description: Block recursive force delete
    pattern: "rm -rf"
    action: deny

  - name: approve-git-push-force
    description: Require approval for force push
    pattern: "git push --force"
    action: require_approval

  - name: block-sensitive-files
    description: Block access to SSH keys
    conditions:
      - "echo $SAFESHELL_COMMAND | grep -q '\\.ssh'"
    action: deny
    ai_only: true

See Rules Guide for complete documentation.

CLI Reference

Core Commands

Command Description
safeshell init Initialize configuration and shims
safeshell check "<cmd>" Check if a command would be allowed
safeshell status Show daemon status
safeshell refresh Regenerate shims from rules

Daemon Commands

Command Description
safeshell daemon start Start the background daemon
safeshell daemon stop Stop the daemon
safeshell daemon restart Restart the daemon
safeshell daemon status Check daemon status

Monitor Commands

Command Description
safeshell monitor Launch the monitor TUI
safeshell monitor --debug Launch with debug panes visible

Integrations

Claude Code

SafeShell integrates with Claude Code via a PreToolUse hook that intercepts Bash commands before execution.

Setup:

Add the hook to your ~/.claude/settings.json (see Quick Start step 5 for the full configuration). The hook is located at ~/.safeshell/hooks/claude_code_hook.py (or in the source tree at src/safeshell/hooks/claude_code_hook.py for development installs).

Requirements:

  • SafeShell daemon must be running (safeshell daemon start)
  • Claude Code must be restarted after changing settings.json

Behavior:

  • allow rules: Command executes normally
  • deny rules: Command is blocked with explanation
  • require_approval rules: Command waits for approval in Monitor TUI

Fail-open design: If the daemon is not running or the hook encounters an error, commands are allowed through. This prevents SafeShell from blocking your workflow if the daemon crashes.

Warp Terminal

SafeShell detects Warp's AI agent mode via the WARP_AI_AGENT environment variable. When WARP_AI_AGENT=1 is set, SafeShell treats commands as AI-originated, enabling ai_only rules.

Setup:

Create a Warp Rule (global or project-level) that instructs Warp's AI agent to set the environment variable before every command:

Option 1: Global Rule (applies to all projects)

In Warp, open Warp Drive > Personal > Rules and add a new global rule:

Always prefix shell commands with `WARP_AI_AGENT=1` to enable SafeShell safety checks.
For example: `WARP_AI_AGENT=1 git push --force`

Option 2: Project Rule (applies to a specific project)

Add a WARP.md file to your project root:

Always prefix shell commands with `WARP_AI_AGENT=1` to enable SafeShell safety checks.
For example: `WARP_AI_AGENT=1 git push --force`

Requirements:

  • SafeShell daemon must be running (safeshell daemon start)
  • Shell integration must be loaded (source ~/.safeshell/init.bash in your shell config)

Behavior: Same as Claude Code — allow, deny, and require_approval rules all apply. Rules with ai_only: true will match commands from Warp's AI agent.

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests and linting (uv run pytest && uv run ruff check src/)
  5. Commit your changes
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Development Guidelines

  • Write tests for new features
  • Follow existing code style (enforced by Ruff)
  • Add type hints to all functions
  • Update documentation for user-facing changes

License

MIT License

Support

Acknowledgments

Built with:

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages