Home
Softono
b

boostsecurityio

Professional software vendor delivering innovative solutions on the Softono platform. Specialized in both open-source and proprietary software development.

Total Products
3

Software by boostsecurityio

poutine
Open Source

poutine

[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8787/badge)](https://www.bestpractices.dev/projects/8787) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/boostsecurityio/poutine/badge)](https://securityscorecards.dev/viewer/?uri=github.com/boostsecurityio/poutine) ![build](https://github.com/boostsecurityio/poutine/actions/workflows/build_test.yml/badge.svg) ![CodeQL](https://github.com/boostsecurityio/poutine/actions/workflows/codeql.yml/badge.svg) [![Go Reference](https://pkg.go.dev/badge/github.com/boostsecurityio/poutine/v4.svg)](https://pkg.go.dev/github.com/boostsecurityio/poutine) [![Go Report Card](https://goreportcard.com/badge/github.com/boostsecurityio/poutine)](https://goreportcard.com/report/github.com/boostsecurityio/poutine) [![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev) [![View site - GH Pages](https://img.shields.io/badge/View_site-GH_Pages-2ea44f?style=for-the-badge)](https://boostsecurityio.github.io/poutine/) # `poutine` Created by [BoostSecurity.io](https://boostsecurity.io), `poutine` is a security scanner that detects misconfigurations and vulnerabilities in the build pipelines of a repository. It supports parsing CI workflows from GitHub Actions and Gitlab CI/CD. When given an access token with read-level access, `poutine` can analyze all the repositories of an organization to quickly gain insights into the security posture of the organization's software supply chain. <table> <td> ![Finding raised by poutine about "Arbitrary Code Execution from Untrusted Code Changes"](https://github.com/boostsecurityio/poutine/assets/172889/ca031a4f-afd8-4e3f-9e66-a2502bd0379b) </td> </table> See the [documentation](docs/content/en/rules) for a list of rules currently supported by `poutine`. ## Why `poutine`? In French, the word "poutine", when not referring to the [dish](https://en.wikipedia.org/wiki/Poutine), can be used to mean "messy". Inspired by the complexity and intertwined dependencies of modern open-source projects, `poutine` reflects both a nod to our Montreal roots and the often messy, complex nature of securing software supply chains. ## Supported Platforms - GitHub Actions - Gitlab Pipelines - Azure DevOps - Pipelines As Code Tekton ## Getting Started ### Installation To install `poutine`, download the latest release from the [releases page](https://github.com/boostsecurityio/poutine/releases) and add the binary to your $PATH. <!-- TODO: cosign verify instructions? --> #### Homebrew ``` bash brew install poutine ``` #### Docker ``` bash docker run -e GH_TOKEN ghcr.io/boostsecurityio/poutine:latest ``` #### GitHub Actions ```yaml ... jobs: poutine: runs-on: ubuntu-latest permissions: security-events: write contents: read steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 ################################################################################################# - name: poutine - GitHub Actions SAST uses: boostsecurityio/poutine-action@main # We recommend to use a tagged version and pin it ################################################################################################# - name: Upload poutine SARIF file uses: github/codeql-action/upload-sarif@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 with: sarif_file: results.sarif ``` ### Usage ``` bash poutine [command] [arguments] [options] ``` #### Analyze a local repository ``` bash poutine analyze_local . ``` #### Analyze a remote GitHub repository ```bash poutine analyze_repo org/repo --token "$GH_TOKEN" ``` #### Analyze all repositories in a GitHub organization ```bash poutine analyze_org org --token "$GH_TOKEN" ``` #### Analyze all projects in a self-hosted Gitlab instance ``` bash poutine analyze_org my-org/project --token "$GL_TOKEN" --scm gitlab --scm-base-url https://gitlab.example.com ``` ### Configuration Options ``` --token SCM access token (required for the commands analyze_repo, analyze_org) (env: GH_TOKEN) --format Output format (default: pretty, json, sarif) --ignore-forks Ignore forked repositories in the organization (analyze_org) --scm SCM platform (default: github, gitlab) --scm-base-url Base URI of the self-hosted SCM instance --threads Number of threads to use (default: 2) --config Path to the configuration file (default: .poutine.yml in the working directory, or .github/poutine.yml) --skip Add rules to the skip list for the current run (can be specified multiple times) --verbose Enable debug logging --fail-on-violation Exit with a non-zero code (10) when violations are found --disable-version-check Disable the once-per-day check for newer poutine releases (env: POUTINE_DISABLE_VERSION_CHECK, config: disableVersionCheck) ``` See [.poutine.sample.yml](.poutine.sample.yml) for an example configuration file. #### Version check telemetry By default, `poutine` reaches out at most once every 24 hours to check whether a newer release is available. The request reports the current poutine version, an anonymous instance identifier persisted in `~/.poutine/config.yaml`, and a count of CLI invocations since the last check. No source, repository, or finding data is sent. To disable, use any of: - `--disable-version-check` flag - `POUTINE_DISABLE_VERSION_CHECK=1` environment variable - `disableVersionCheck: true` in `.poutine.yml` ### Custom Rules `poutine` supports custom Rego rules to extend its security scanning capabilities. You can write your own rules and include them at runtime. #### Configuration Create a `.poutine.yml` configuration file in your current working directory, or keep it alongside your other GitHub metadata at `.github/poutine.yml` — both are auto-discovered. When both exist, `.poutine.yml` at the repo root wins. To use a custom path, pass the `--config` flag (which takes precedence over both): ```bash poutine analyze_local . --config my-config.yml ``` In your configuration file, specify the path(s) to your custom rules using the `include` directive: ```yaml include: - path: ./custom_rules - path: ./github_actions ``` #### Writing Custom Rules Custom Rego rules must: 1. Be saved as `*.rego` files in the included directory 2. Follow the package naming convention: `package rules.<rule_name>` 3. Define a `rule` variable with metadata 4. Define a `results` set containing findings **Example custom rule:** ```rego package rules.custom_injection import data.poutine import rego.v1 # METADATA # title: Custom Injection Detection # description: Detects potential injection vulnerabilities in workflows # custom: # level: warning rule := poutine.rule(rego.metadata.chain()) # Define pattern to detect (properly escaped for Rego) patterns.github contains `\\$\\{\\{[^\\}]+\\}\\}` results contains poutine.finding(rule, pkg.purl, { "path": workflow.path, "line": step.lines.run, "job": job.id, "step": i, "details": "Potential injection found in step", }) if { pkg := input.packages[_] workflow := pkg.github_actions_workflows[_] job := workflow.jobs[_] step := job.steps[i] step.run # Ensure step has a run command regex.match(patterns.github[_], step.run) } ``` **Key points:** - Use `import data.poutine` and `import rego.v1` for modern Rego syntax and poutine utilities - Use `rule := poutine.rule(rego.metadata.chain())` to extract metadata from METADATA comments - The `package` name determines the rule identifier (e.g., `package rules.custom_injection` → rule ID: `custom_injection`) - Add METADATA comments to describe the rule with `title`, `description`, and `level` - Set the severity `level` to `note`, `warning`, or `error` - Use `poutine.finding(rule, pkg.purl, {...})` to create findings that match the poutine schema - The `results` set should contain findings with fields like `path`, `line`, `job`, `step`, `details` For more examples, see: - [poutine-rules repository](https://github.com/boost-rnd/poutine-rules) - External rule examples - Built-in rules in [opa/rego/rules/](./opa/rego/rules/) directory - [.poutine.sample.yml](.poutine.sample.yml) - Configuration examples ### Acknowledging Findings `poutine` supports skipping (acknowledging) specific findings that are not relevant in your context. This can be useful when: - A finding is a false positive - The security concern has been addressed through other means (e.g., hardened self-hosted runners) - You've accepted the risk for a particular finding To acknowledge findings, you can either: 1. Add a `skip` section to your `.poutine.yml` configuration file 2. Use the `--skip` command-line flag (e.g., `--skip rule_name`) for one-time skipping #### Configuration File Add a `skip` section to your `.poutine.yml` configuration file. Each skip rule can filter findings by: - `job`: Filter by job name - `level`: Filter by severity level (note, warning, error) - `path`: Filter by workflow file path - `rule`: Filter by rule name - `purl`: Filter by package URL - `osv_id`: Filter by OSV ID Example configuration: ```yaml skip: # Skip all note-level findings - level: note # Skip findings in a specific workflow - path: .github/workflows/safe.yml # Skip a specific rule everywhere - rule: unpinnable_action # Skip a rule for specific workflows - rule: pr_runs_on_self_hosted path: - .github/workflows/pr.yml - .github/workflows/deploy.yml # Skip findings for specific packages - rule: github_action_from_unverified_creator_used purl: - pkg:githubactions/dorny/paths-filter ``` For more examples, see [.poutine.sample.yml](.poutine.sample.yml). #### Command Line You can also skip rules on the command line using the `--skip` flag. Note that the command-line flag only supports skipping rules by name globally and does not support the granular filtering options (job, path, level, etc.) available in the configuration file. ```bash # Skip a single rule globally poutine analyze_repo org/repo --skip unpinnable_action # Skip multiple rules globally poutine analyze_repo org/repo --skip unpinnable_action --skip pr_runs_on_self_hosted ``` This is useful for one-time analysis or when you want to temporarily ignore specific rules without modifying your configuration file. For more granular control (e.g., skipping a rule only in specific workflows), use the configuration file instead. ## AI Coding Assistant Integration (MCP) `poutine` can be integrated with AI coding assistants like Claude Code, Gemini, etc. through the Model Context Protocol (MCP). This allows AI assistants to analyze repositories and validate CI/CD pipelines directly from your development environment. For detailed setup instructions for your specific AI coding tool, see the [MCP Integration Guide](MCP_INTEGRATION.md). ## Building from source Building `poutine` requires Go 1.26+. ```bash git clone https://github.com/boostsecurityio/poutine.git cd poutine make build ``` ## Development ### Updating Build Platform CVE Database ```bash go test -tags build_platform_vuln_database ./... opa fmt -w opa/rego/external/build_platform.rego ``` ## See Also For examples of vulnerabilities in GitHub Actions workflows, you can explore the [Messy poutine GitHub organization](https://github.com/messypoutine). It showcases real-world vulnerabilities from open-source projects readily exploitable for educational purposes. To get started with some hints, try using `poutine` to analyze the `messypoutine` organization: ``` bash poutine analyze_org messypoutine --token `gh auth token` ``` You may submit the flags you find in a [private vulnerability disclosure](https://github.com/messypoutine/.github/security/advisories/new). ## License This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

CI / CD Vulnerability Scanning
470 Github Stars
smokedmeat
Open Source

smokedmeat

# SmokedMeat [![License: AGPL v3](https://img.shields.io/badge/License-AGPLv3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) **CI/CD Red Team Framework** > Like Metasploit, but for CI/CD pipelines. *From the makers of the [poutine](https://github.com/boostsecurityio/poutine) Build Pipeline SAST scanner at [BoostSecurity Labs](https://labs.boostsecurity.io).* ![SmokedMeat quickstart demo](https://vhs.charm.sh/vhs-5J9lw1pcFCtE51X6EiaeWM.gif) --- > **Warning: This tool is for authorized security testing only.** > > SmokedMeat exists because CI/CD pipeline threats are deeply underestimated. Traditional security training rarely covers supply chain attacks, leaving defenders unprepared for techniques that adversaries actively exploit in the wild. > > We built this to give security teams the ability to learn, practice, and validate defenses against advanced CI/CD attack techniques through realistic red team exercises. > > **Only use against systems you own or have explicit written permission to test.** --- ## What is SmokedMeat? SmokedMeat is a post-exploitation framework for CI/CD pipelines. Point it at a GitHub organization, let it find vulnerable workflows, deploy an implant to a compromised runner, then pivot through cloud providers, extract secrets, and map the blast radius - all from a terminal UI. **What it does:** 1. **Analyze** - Scan an org's GitHub Actions workflows for injection vulnerabilities, dangerous triggers, and unsafe checkout patterns (powered by [poutine](https://github.com/boostsecurityio/poutine)) 2. **Exploit** - Deploy a stager via PR, issue, comment, or workflow dispatch. When the vulnerable workflow runs, it downloads and executes the implant on the CI runner. 3. **Post-exploit** - Extract secrets from runner memory, enumerate GitHub token permissions, scan for private keys, and collect loot 4. **Pivot** - Use captured credentials to move laterally: discover private repos, mint GitHub App tokens, exchange OIDC tokens for AWS/GCP/Azure access, probe SSH deploy keys **Philosophy:** Bold and noisy. This isn't an EDR evasion tool. It's a demonstration framework that shows how deep a CI/CD compromise goes before anything triggers an alert. **Who is it for:** - Red teams validating CI/CD security posture in enterprise environments - Pentesters demonstrating supply chain attack paths to stakeholders - Security engineers testing detection and response for pipeline attacks - Researchers developing new CI/CD exploitation techniques - Bug bounty hunters exploring supply chain attack surface ## Quick Start To try SmokedMeat for the first time, install Docker and `make`. Go is not required. ```bash git clone https://github.com/boostsecurityio/smokedmeat.git cd smokedmeat make quickstart ``` `make quickstart` is the recommended first run. It starts the stable release quickstart stack locally and launches the operator TUI (`Counter`) against the local C2 teamserver (`Kitchen`). Recommended first run: - Target: `whooli` - Token: classic PAT with `public_repo` ⚠ Prefer a classic PAT. Fine-grained PATs can be too restrictive and may block testing public targets in other orgs, including `whooli`. `whooli` is SmokedMeat's deliberately vulnerable CI/CD attack playground. It is the recommended first target for the public path. The setup wizard walks you through: 1. **GitHub PAT** - Enter your token. For private repos, a classic PAT will usually need `repo`. 2. **Target** - Enter `whooli` or your own org/repo 3. **Analysis** - Scans workflows for vulnerabilities and presents exploitable findings For the full challenge flow, see the [`whooli` guide](docs/WHOOLI.md) or go straight to the [`whooli` GitHub org](https://github.com/whooli). When you are done: ```bash make quickstart-down # Stop containers make quickstart-purge # Stop and delete all data ``` If you want to work from source instead, see [Development](#development). ## Development If you are contributing or iterating on the source tree locally, install Go 1.26+ and use the dev quickstart: ```bash make dev-quickstart ``` `make dev-quickstart` builds the local `smokedmeat-cloud-shell` image, starts `cloudflared`, `nats`, and the C2 teamserver (`Kitchen`), then launches the operator TUI from source. If you want the infrastructure first and the operator TUI later: ```bash make dev-quickstart-up make dev-quickstart-counter ``` When you are done: ```bash make dev-quickstart-down # Stop containers make dev-quickstart-purge # Stop and delete all data ``` More deployment modes and local development details are in [docs/deployment.md](docs/deployment.md). ## Version Check Counter checks for newer SmokedMeat releases at startup. It can be disabled by setting the `SMOKEDMEAT_DISABLE_VERSION_CHECK` environment variable. ## Core Components | Standard term | SmokedMeat name | Description | |---------------|-----------------|-------------| | **Operator TUI** | `Counter` | Terminal interface for analysis, payload delivery, and post-exploitation workflow. | | **C2 teamserver** | `Kitchen` | API and WebSocket server for operator sessions, stagers, callbacks, and graph state. | | **Implant** | `Brisket` | Agent delivered to compromised CI runners for beaconing, command execution, and pivoting. | | **Browser graph view** | `Browser View` | Live attack graph served by the C2 teamserver at `/graph`. | ## Deployment Modes | Mode | Use it when | Entry point | |------|-------------|-------------| | **Quickstart** | Fastest first run on the pinned release | `make quickstart` | | **Dev Quickstart** | Working on the source tree locally | `make dev-quickstart` | | **Hosted Teamserver** | Running a real engagement with a stable domain | [docs/deployment.md](docs/deployment.md) | Hosted Teamserver runs the C2 teamserver on a dedicated host and the operator TUI natively on each operator workstation. ## Architecture At a high level, the operator TUI (`Counter`) talks to the C2 teamserver (`Kitchen`), which manages implants (`Brisket`) running on compromised CI runners and serves the live attack graph. ``` ┌──────────────┐ │ SSH AGENT │ │ (Auth) │ └──────┬───────┘ │ ▼ ┌──────────────┐ ┌──────────────┐ │ THE COUNTER │ ───────────────▶│ THE KITCHEN │ │ (Operator) │ WebSocket │ (Teamserver) │ │ Bubbletea │◀─────────────── │ │ │ TUI │ Events/Graph │ ┌──────────┐ │ └──────────────┘ │ │ Database │ │ │ └──────────┘ │ ┌──────────────┐ │ │ │ BROWSER │ ───────────────▶│ │ │ Graph View │ WebSocket │ │ │ Visualizer │◀─────────────── │ │ └──────────────┘ Live Updates └──────────────┘ │ ▲ │ │ Creates PR │ │ Stager fetches implant binary │ │ Implant HTTP Beacon/Commands ▼ │ ┌────────────────────────────────────────────┴──────────────────────────────────┐ │ GITHUB.COM │ │ │ │ ┌─────────────────────┐ ┌─────────────────────────────────────────┐ │ │ │ Malicious PR │ triggers │ GitHub Actions Runner │ │ │ │ (Vulnerable │─────────▶│ │ │ │ │ Workflow) │ │ ┌────────────┐ ┌────────────────┐ │ │ │ └─────────────────────┘ │ │ Stager │─────▶│ THE BRISKET │ │ │ │ │ │ │ │ (Implant) │ │ │ │ │ └────────────┘ └────────────────┘ │ │ │ └─────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────────────────────────┘ ``` ## Features Full details in [docs/FEATURES.md](docs/FEATURES.md). | Category | Capabilities | |----------|-------------| | **Reconnaissance** | Auto-detect 6 CI platforms (GitHub Actions, GitLab CI, Azure DevOps, CircleCI, Jenkins, Bitbucket). Classify secrets, probe OIDC availability, gather runner metadata. | | **Secret Extraction** | Scan Runner.Worker process memory via `/proc` to recover unmasked `secrets.*`, `vars.*`, and `GITHUB_TOKEN` permission maps that GitHub hides from logs. | | **Vulnerability Analysis** | Embedded [poutine](https://github.com/boostsecurityio/poutine) SAST for injection vulnerabilities, dangerous triggers, and workflow `if:` gate classification. Gitleaks deep scan for private keys and PATs in git history. | | **Delivery** | 5 automated methods: PR, issue, comment, LOTP, workflow dispatch - plus copy-only and manual. Draft PR support, auto-close on callback, server-side dispatch preflight. | | **Injection Payloads** | Context-aware payload generation for 8 injection vectors (branch name, PR title/body, commit message, issue title/body, github-script, bash run) with constraint-aware techniques. | | **LOTP** | Living Off The Pipeline catalog: 15 build tools (npm, pip, cargo, make, docker, gradle, maven, and more) with config-file payloads for code execution during install/build/test. | | **Cache Poisoning** | Writer/victim classification, exact cache key prediction, archive staging via the Actions Cache API. Wizard-driven flow with implant arming. | | **Token Enumeration** | Probe GitHub tokens against API endpoints to enumerate 10 permission scopes, identify token type, and list accessible repos and orgs. | | **Cloud Pivots** | OIDC token exchange for AWS (`sts:AssumeRoleWithWebIdentity`), GCP (Workload Identity Federation), Azure (AAD), and Kubernetes. Post-pivot resource enumeration. | | **Cloud Shell** | Durable local sessions with `cloud shell` (pre-configured gcloud/aws/az), `cloud export`, and provider quick checks. | | **SSH Pivoting** | Probe repos for SSH deploy key access (read/write), `ssh shell` with temporary agent, confirmed access persisted to graph. | | **GitHub Pivoting** | `pivot github` for repo discovery, `pivot app` for GitHub App PEM-to-installation-token exchange. Discovered repos auto-queued for analysis. | | **Attack Graph** | Persistent directed graph (BBolt) with org/repo/workflow/job/vuln/token/cloud nodes. Live Cytoscape.js browser visualization at `/graph`. | | **Operator TUI** | Phase-aware workflow, 7-step setup wizard, attack tree navigation, exploit wizard, loot stash, omnibox search, tab completion, OSC 8 hyperlinks. | | **Teamserver** | SSH or token auth, NATS JetStream message bus, GitHub API proxy (tokens stay server-side), auto-TLS via Caddy, operation history. | ## Technology Stack | Layer | Technology | |-------|------------| | Language | Go 1.26+ | | TUI Framework | [Bubbletea v2](https://github.com/charmbracelet/bubbletea) + [Lipgloss v2](https://github.com/charmbracelet/lipgloss) | | TUI Layout | [Ultraviolet](https://github.com/charmbracelet/ultraviolet) layout + ANSI-safe screen compositing | | Message Bus | [NATS JetStream](https://nats.io/) | | Attack Graph | [hmdsefi/gograph](https://github.com/hmdsefi/gograph) | | Graph Visualization | [Cytoscape.js](https://js.cytoscape.org/) | | Database | [BBolt](https://github.com/etcd-io/bbolt) | | CI/CD Scanner | [poutine](https://github.com/boostsecurityio/poutine) (embedded) | | Secret Scanner | [gitleaks](https://github.com/gitleaks/gitleaks) (embedded, custom rules) | | Runner Secret Extraction | gump (embedded, `/proc` memory scanning) | | Cloud SDKs | AWS SDK v2, Google Cloud, Azure SDK for Go | | Reverse Proxy | [Caddy](https://caddyserver.com/) (auto-TLS) | ## Testing ```bash make test # Unit tests make lint # Linter make e2e-smoke # Fast public exploit smoke path make e2e-goat # Full goat chain to the cloud flag ``` ## Prior Art SmokedMeat builds on research from: - [poutine](https://github.com/boostsecurityio/poutine) - Build Pipeline SAST scanner - [LOTP](https://boostsecurityio.github.io/lotp/) - Living Off The Pipeline techniques - [Gato-X](https://github.com/AdnaneKhan/Gato-X) - GitHub Actions enumeration - [Nord-Stream](https://github.com/synacktiv/nord-stream) - CI/CD secret extraction - [Sliver](https://github.com/BishopFox/sliver) - Go C2 architecture patterns - [Mythic](https://docs.mythic-c2.net/) - Collaborative workflow design ## License GNU Affero General Public License v3.0 - see [LICENSE](LICENSE) for details. --- *Built for defenders who want to understand attacker techniques.*

Testing & QA Vulnerability Scanning
330 Github Stars
bagel
Open Source

bagel

# Bagel > Inventory what matters on developer machines—tools, configs, and **metadata about secrets**—to improve org supply‑chain security without exfiltrating payloads. --- ## What is it? Bagel is a cross‑platform CLI that inspects developer workstations (macOS, Linux, Windows) and produces a structured report of: * **Dev tool configurations and risky settings** across 9 probes: Git, SSH, npm, environment variables, shell history, cloud credentials (AWS/GCP/Azure), JetBrains IDEs, GitHub CLI, and AI CLI tools. * **Secret locations (metadata only)**: presence of tokens, keys, and credentials in config files, env vars, and history—detected by 8 secret detectors—**never the secret values**. For detailed documentation on each probe and detector, see the [Bagel docs site](https://boostsecurityio.github.io/bagel/). --- ## Privacy & Safety by Design * **No payloads. Ever.** Bagel records only metadata (path, owner, perms, timestamps, config flags, key type/length/expiry). Secret values are never included in output or written to disk. * **Local‑first.** Reports are printed to stdout as JSON by default. * **Minimally intrusive.** Read‑only operations; no process injection; no network scanners. * **Transparent.** Every probe is documented and can be toggled via configuration. --- ## Why run it? Modern supply‑chain risk often lands on developer endpoints (malicious packages, misconfig creds, weak key hygiene). Bagel standardizes visibility so security teams can: * Find high‑signal misconfigs (e.g., `http.sslVerify=false`, `ForwardAgent yes`, plaintext creds files, unencrypted SSH keys). * Detect leaked secrets in shell history, `.env` files, and config files. * Enforce baseline posture checks in CI with `--strict`. --- ## Risk checks (examples) * **Git**: `credential.helper=store`, `http.sslVerify=false`, custom `core.sshCommand` with non‑standard binaries, dangerous protocols, fsck disabled. * **npm**: tokens in `.npmrc`, `strict-ssl=false`, HTTP (non‑HTTPS) registries. * **SSH**: keys without passphrase, `ForwardAgent yes`, `StrictHostKeyChecking=no`, permissive file modes. * **Environment & history**: secrets embedded in env vars, `.env` files, or shell command history. * **Cloud**: AWS credentials, GCP API keys, Azure storage keys in config files. --- ## Installation ### Pre-built Binaries Download the latest release from [GitHub Releases](https://github.com/boostsecurityio/bagel/releases). **macOS:** ```bash # Intel Mac curl -sL https://github.com/boostsecurityio/bagel/releases/latest/download/bagel_Darwin_x86_64.tar.gz | tar xz sudo mv bagel /usr/local/bin/ # Apple Silicon curl -sL https://github.com/boostsecurityio/bagel/releases/latest/download/bagel_Darwin_arm64.tar.gz | tar xz sudo mv bagel /usr/local/bin/ ``` **Homebrew:** ```bash brew install bagel ``` **Linux:** ```bash # x86_64 curl -sL https://github.com/boostsecurityio/bagel/releases/latest/download/bagel_Linux_x86_64.tar.gz | tar xz sudo mv bagel /usr/local/bin/ # ARM64 curl -sL https://github.com/boostsecurityio/bagel/releases/latest/download/bagel_Linux_arm64.tar.gz | tar xz sudo mv bagel /usr/local/bin/ ``` **Windows:** Download `bagel_Windows_x86_64.zip` from the [releases page](https://github.com/boostsecurityio/bagel/releases), extract it, and add it to your PATH. ```powershell Invoke-WebRequest -Uri "https://github.com/boostsecurityio/bagel/releases/latest/download/bagel_Windows_x86_64.zip" -OutFile "bagel.zip" Expand-Archive -Path "bagel.zip" -DestinationPath "." ``` ### Build from Source Requires Go 1.25 or later. ```bash git clone https://github.com/boostsecurityio/bagel.git cd bagel go build -o bagel ./cmd/bagel ``` ### Verify Installation ```bash bagel version ``` --- ## Usage ```bash bagel scan ``` This scans your workstation and outputs findings to stdout in JSON format. ### Common flags | Flag | Description | |------|-------------| | `--format`, `-f` | Output format: `json` (default), `table` | | `--output`, `-o` | Write output to a file instead of stdout | | `--strict` | Exit with code 2 if any findings are detected | | `--no-cache` | Bypass file index cache and force rebuild | | `--no-progress` | Disable progress bars | | `--verbose`, `-v` | Enable verbose (debug) logging | | `--config` | Path to configuration file | | `--disable-version-check` | Disable the once-per-day check for newer bagel releases (env: `BAGEL_DISABLE_VERSION_CHECK`, config: `disable_version_check`) | ### Examples ```bash # Save report to a file bagel scan -o report.json # Table output for quick review bagel scan -f table # CI gate: fail the build if findings exist bagel scan --strict # Debug a specific scan bagel scan --verbose --no-progress ``` --- ## Configuration Bagel uses a YAML configuration file. It looks for `bagel.yaml` in these locations (in order): 1. Path specified with `--config` 2. Current directory (`./bagel.yaml`) 3. Platform config directory (`~/.config/bagel/bagel.yaml` on Unix, `%APPDATA%\bagel\bagel.yaml` on Windows) ### Example configuration ```yaml version: 1 probes: git: enabled: true ssh: enabled: true npm: enabled: true env: enabled: true shell_history: enabled: true cloud: enabled: true jetbrains: enabled: true gh: enabled: true ai_credentials: enabled: true ai_chats: enabled: true privacy: redact_paths: [] exclude_env_prefixes: [] output: include_file_hashes: false include_file_content: false ``` All probes are enabled by default. To disable a probe, set `enabled: false`. ### Version check telemetry By default, `bagel` reaches out at most once every 24 hours to check whether a newer release is available. The request reports the current bagel version, an anonymous instance identifier persisted under the platform config directory (`~/.config/bagel/version-check.yaml` on Unix, `%APPDATA%\bagel\version-check.yaml` on Windows), and a count of CLI invocations since the last check. No scan, host, or finding data is sent. To disable, use any of: - `--disable-version-check` flag - `BAGEL_DISABLE_VERSION_CHECK=1` environment variable - `disable_version_check: true` in `bagel.yaml` --- ## Output schema (excerpt) ```json { "metadata": { "version": "0.1.0", "timestamp": "2026-02-10T12:00:00Z", "duration": "1.234s" }, "host": { "hostname": "dev-laptop", "os": "darwin", "arch": "arm64", "username": "dev", "system": { "os_version": "15.3", "kernel_version": "Darwin 25.2.0", "cpu_model": "Apple M1", "cpu_cores": 8, "ram_total_gb": 16 } }, "findings": [ { "id": "git-ssl-verify-disabled", "probe": "git", "severity": "high", "title": "Git SSL Verification Disabled", "message": "Git is configured to skip SSL certificate verification...", "path": "git-config:http.sslverify" }, { "id": "ssh-private-key-rsa", "probe": "ssh", "severity": "critical", "title": "Unencrypted SSH Private Key Detected (RSA)", "message": "An unencrypted RSA SSH private key was detected...", "path": "file:/Users/dev/.ssh/id_rsa" } ] } ``` --- ## Architecture * **Probes**: small, hermetic modules that scan specific areas of the system. * **Detectors**: reusable secret detection patterns used by probes. * **Collector**: orchestrates probes with timeouts and resource caps. * **Reporters**: render JSON or table output; emit exit codes for CI. Each probe declares its scope (user/system), paths touched, env vars read, and risk rules it can emit. ### Current Probes | Probe | Description | What it checks | |-------|-------------|----------------| | `git` | Git configuration security | SSL verification disabled, SSH config issues (StrictHostKeyChecking, UserKnownHostsFile), plaintext credential storage (`credential.helper=store`), dangerous protocols (ext, fd, file), fsck disabled, proxy settings, custom hooks path | | `ssh` | SSH configuration and key security | `StrictHostKeyChecking=no`, `UserKnownHostsFile=/dev/null`, `ForwardAgent=yes`, private key file permissions, unencrypted private keys | | `npm` | NPM/Yarn configuration | `.npmrc` and `.yarnrc` files: `strict-ssl=false`, HTTP (non-HTTPS) registries, `always-auth` settings | | `env` | Environment variables and dotfiles | Environment variables, shell config files (`.bashrc`, `.zshrc`), `.env` files for embedded secrets | | `shell_history` | Shell history files | `.bash_history`, `.zsh_history` for secrets in command history | | `cloud` | Cloud provider credentials | AWS (`~/.aws/config`, `~/.aws/credentials`), GCP (`~/.config/gcloud/`), Azure config files | | `jetbrains` | JetBrains IDE configuration | JetBrains IDE workspace files and configuration for embedded secrets | | `gh` | GitHub CLI | GitHub CLI authentication tokens and configuration | | `ai_cli` | AI CLI tools | Credential files and chat logs for Gemini, Codex, Claude, and OpenCode | ### Current Detectors | Detector | Description | Patterns detected | |----------|-------------|-------------------| | `github-token` | GitHub authentication tokens | Classic PAT (`ghp_`), Fine-grained PAT (`github_pat_`), OAuth (`gho_`), App User-to-Server (`ghu_`), App Server-to-Server (`ghs_`), Refresh Token (`ghr_`) | | `npm-token` | NPM authentication tokens | NPM auth tokens (`npm_*`) | | `ai-service` | AI service API keys | OpenAI (`sk-`), Anthropic (`sk-ant-api03-`, `sk-ant-admin01-`), Hugging Face (`hf_`, `api_org_`) | | `http-authentication` | HTTP auth credentials | Bearer tokens, Basic Auth headers, API key headers (`X-API-Key`, etc.), Basic Auth in URLs (`http://user:pass@host`) | | `ssh-private-key` | SSH private keys | RSA, DSA, EC, OPENSSH, PKCS8 keys; detects encrypted vs unencrypted | | `cloud-credentials` | Cloud provider credentials | AWS Access Key ID (`AKIA*`, `ASIA*`, etc.), GCP API Key (`AIza*`), Azure Storage Account Key | | `generic-api-key` | Generic secrets | High-entropy strings matching common secret patterns (uses Shannon entropy analysis) | | `jwt` | JSON Web Tokens | JWT tokens (`eyJ` prefix with standard JWT structure) | --- ## Platform support | OS | Support | |----|---------| | macOS (Intel & Apple Silicon) | Full support | | Linux (x86_64 & ARM64) | Full support | | Windows (x86_64) | Full support with platform-specific file paths and PowerShell history | All probes work cross-platform with appropriate path handling for each OS. --- ## Scrub Command > **Fork addition** -- not in upstream Bagel. `bagel scrub` removes credentials from AI CLI session logs and shell history files, replacing them with `[REDACTED-<type>]` markers while preserving conversation context. ```bash # Scan and interactively confirm (default) bagel scrub # Skip prompt, apply immediately bagel scrub --yes # Scan only, no modifications bagel scrub --dry-run # Scrub without grace period (includes recent files) bagel scrub --yes --grace-minutes 0 # Scrub a single file bagel scrub --yes --file ~/.claude/projects/foo/abc123.jsonl ``` | Flag | Default | Description | |------|---------|-------------| | `--yes` / `-y` | `false` | Skip confirmation prompt and apply changes | | `--dry-run` | `false` | Scan and report only, do not modify files | | `--grace-minutes` | `60` | Skip files modified within this many minutes | | `--file` | | Scrub a single file instead of all eligible files | **Targets:** - `~/.claude/projects/**/*.jsonl` -- Claude Code session logs - `~/.claude/projects/**/*.txt` -- Claude Code tool results - `~/.codex/sessions/**/*.jsonl` -- Codex CLI session logs - `~/.gemini/tmp/*/chats/*.json` -- Gemini CLI chat logs - `~/.local/share/opencode/**/*.json` -- OpenCode session logs - `~/.bash_history` -- Bash shell history - `~/.zsh_history` -- Zsh shell history - `~/.sh_history` -- Generic shell history - `~/.local/share/fish/fish_history` -- Fish shell history **Recommended workflow:** 1. `bagel scan -f table` -- assess your exposure 2. `bagel scrub --yes` -- clean up 3. `bagel scan -f table` -- verify reduction 4. Rotate any credentials that were found --- ## Integrations * **CI**: run `bagel scan --strict` in your pipeline to fail builds when findings are detected. --- ## Exit codes * `0` – success, no findings detected (or `--strict` not set) * `1` – runtime error * `2` – findings detected (when using `--strict`) --- ## FAQ **Does it read my secrets?** No. It only gathers metadata and security‑relevant flags. **Is it noisy?** Probes are read‑only, batched, and time‑boxed to keep scans under a minute on typical dev machines. ---

Terminal & CLI Tools Vulnerability Scanning
146 Github Stars