|
| 1 | +# Bashtion 🛡️ |
| 2 | + |
| 3 | +Bashtion intercepts shell scripts before they hit your interpreter. It captures the script, runs static and AI-powered safety analysis, shows you the findings, and only executes after you explicitly confirm. Think of it as "curl | bash" with a security checkpoint. |
| 4 | + |
| 5 | +[](https://www.rust-lang.org) |
| 6 | +[](LICENSE) |
| 7 | +[](https://github.com/chriswessels/bashtion/actions) |
| 8 | +[](https://github.com/chriswessels/bashtion/releases) |
| 9 | + |
| 10 | +## ✨ Features |
| 11 | + |
| 12 | +- **🛡️ Double Analysis**: Tree-sitter-based static checks plus LLM intent/risk summaries on every script |
| 13 | +- **🔍 Full Transparency**: Shows exact code snippets for each finding, logs overall risk, and requires your confirmation |
| 14 | +- **💻 Shell-Agnostic**: Supports any `stdin` source (`curl ... | bashtion`) and runs in whatever shell you configure |
| 15 | +- **⚙️ Structured Reports**: Colorized terminal output, structured JSON verdicts, and manual review prompt by default |
| 16 | +- **🧪 Manual Test Scripts**: Sample scripts (`scripts/manual/*.sh`) exercise different detections for easy regression testing |
| 17 | +- **🔌 Configurable Backend**: Works with OpenAI-compatible endpoints (override base URL, key, model, timeouts) and falls back gracefully when AI is unavailable |
| 18 | +- **📦 Installer**: Single `install.sh` fetches the correct binary for macOS/Linux and keeps the repo overrideable via env vars |
| 19 | + |
| 20 | +## 🚀 Quick Start |
| 21 | + |
| 22 | +### Installation |
| 23 | + |
| 24 | +#### 📦 Pre-built Binaries |
| 25 | + |
| 26 | +```bash |
| 27 | +curl -fsSL https://raw.githubusercontent.com/chriswessels/bashtion/main/install.sh | bash |
| 28 | +``` |
| 29 | + |
| 30 | +Manual downloads: grab the latest tarball for your platform from the [releases page](https://github.com/chriswessels/bashtion/releases/latest). |
| 31 | + |
| 32 | +#### 🔧 From Source (Rust 1.83+) |
| 33 | + |
| 34 | +```bash |
| 35 | +git clone https://github.com/chriswessels/bashtion |
| 36 | +cd bashtion |
| 37 | +cargo install --path . |
| 38 | +``` |
| 39 | + |
| 40 | +#### 📋 Verify Installation |
| 41 | + |
| 42 | +```bash |
| 43 | +bashtion --version |
| 44 | +``` |
| 45 | + |
| 46 | +### Basic Usage |
| 47 | + |
| 48 | +```bash |
| 49 | +# Inspect a remote installer before execution |
| 50 | +curl https://example.com/install.sh | bashtion |
| 51 | + |
| 52 | +# Capture stdin but skip execution (print script to stdout) |
| 53 | +curl https://example.com/install.sh | bashtion --no-exec |
| 54 | + |
| 55 | +# Use a custom OpenAI-compatible endpoint |
| 56 | +BASHTION_OPENAI_BASE_URL=https://llm.example.com/v1 \ |
| 57 | +BASHTION_OPENAI_API_KEY=sk-... \ |
| 58 | +curl https://example.com/install.sh | bashtion |
| 59 | + |
| 60 | +# Force a different shell to execute the approved script |
| 61 | +BASHTION_EXEC_SHELL=/bin/zsh curl https://example.com/install.sh | bashtion |
| 62 | + |
| 63 | +# Analyze a local script non-interactively |
| 64 | +bashtion < scripts/manual/static_eval.sh |
| 65 | +``` |
| 66 | + |
| 67 | +During each run Bashtion: |
| 68 | +1. Reads stdin into a bounded buffer (default 500 KB) |
| 69 | +2. Runs static analysis and AI analysis (if configured) |
| 70 | +3. Presents findings + summary |
| 71 | +4. Prompts “[y/N]” before actually executing the script via your shell (unless `--no-exec`) |
| 72 | + |
| 73 | +## ⚙️ Configuration |
| 74 | + |
| 75 | +All settings can be controlled via CLI flags or `BASHTION_*` env vars: |
| 76 | + |
| 77 | +| Flag / Env | Description | Default | |
| 78 | +|------------|-------------|---------| |
| 79 | +| `--no-exec` / `BASHTION_AUTO_EXEC=false` | Skip shell execution; print script instead | auto-exec on | |
| 80 | +| `--exec-shell` / `BASHTION_EXEC_SHELL` | Shell command used to run approved scripts | `/bin/bash` | |
| 81 | +| `--timeout-secs` / `BASHTION_TIMEOUT_SECS` | HTTP timeout for AI calls | 30s | |
| 82 | +| `--buffer-limit` / `BASHTION_BUFFER_LIMIT` | Max bytes read from stdin | 512 KB | |
| 83 | +| `BASHTION_OPENAI_BASE_URL` | OpenAI-compatible endpoint base URL | unset (AI disabled) | |
| 84 | +| `BASHTION_OPENAI_API_KEY` | API key for the endpoint | unset | |
| 85 | +| `BASHTION_OPENAI_MODEL` | Model name sent to the endpoint | `gpt-4o` | |
| 86 | + |
| 87 | +Example: |
| 88 | +```bash |
| 89 | +BASHTION_OPENAI_BASE_URL=http://localhost:8080/v1 \ |
| 90 | +BASHTION_OPENAI_API_KEY=dev-secret \ |
| 91 | +BASHTION_OPENAI_MODEL=local-mixtral \ |
| 92 | + curl https://example.com/install.sh | bashtion |
| 93 | +``` |
| 94 | + |
| 95 | +## 🧪 Manual Test Scripts |
| 96 | + |
| 97 | +Use the bundled scripts to validate detections: |
| 98 | + |
| 99 | +```bash |
| 100 | +# Triggers the eval static rule |
| 101 | +cat scripts/manual/static_eval.sh | bashtion --no-exec |
| 102 | + |
| 103 | +# Shows curl|bash caution |
| 104 | +cat scripts/manual/static_curl_pipe.sh | bashtion --no-exec |
| 105 | + |
| 106 | +# Benign download (AI low risk) |
| 107 | +cat scripts/manual/semantic_download.sh | bashtion --no-exec |
| 108 | + |
| 109 | +# Reverse shell (AI + static high risk) |
| 110 | +cat scripts/manual/semantic_reverse_shell.sh | bashtion --no-exec |
| 111 | +``` |
| 112 | + |
| 113 | +## 🤖 AI Backend |
| 114 | + |
| 115 | +- Bashtion sends the captured script to `POST {base_url}/chat/completions` with a structured-output prompt. |
| 116 | +- The model must respond with JSON: `{ "intent": ..., "risk": "low|medium|high", "findings": [...] }`. |
| 117 | +- Responses are retried up to 3 times with exponential backoff, and malformed JSON is auto-repaired with [`llm_json`](https://crates.io/crates/llm_json). |
| 118 | +- If no base URL is configured, AI analysis is skipped (only static findings are shown). |
| 119 | + |
| 120 | +## 📦 Release Artifacts |
| 121 | + |
| 122 | +`install.sh` and the GitHub release workflow publish four archives: |
| 123 | + |
| 124 | +- `bashtion-linux-x86_64.tar.gz` |
| 125 | +- `bashtion-linux-aarch64.tar.gz` |
| 126 | +- `bashtion-macos-x86_64.tar.gz` |
| 127 | +- `bashtion-macos-aarch64.tar.gz` |
| 128 | + |
| 129 | +Each contains a single `bashtion` binary. SHA256 files are provided for integrity checks. |
| 130 | + |
| 131 | +## 📄 License |
| 132 | + |
| 133 | +Bashtion is MIT-licensed. See [LICENSE](LICENSE) for details. |
| 134 | + |
| 135 | +## 🙏 Acknowledgments |
| 136 | + |
| 137 | +Inspired by projects like Nomnom and LIGMA that focus on safe, AI-friendly tooling for developers. |
0 commit comments