boostsecurityio/bagel
GitHub: boostsecurityio/bagel
跨平台开发者终端安全审计工具,用于检测开发工具配置风险和敏感凭证泄露。
Stars: 89 | Forks: 7
# Bagel
## 它是什么?
Bagel 是一个跨平台 CLI,用于检查开发者工作站(macOS、Linux、Windows)并生成结构化报告,内容包括:
* **开发工具配置和风险设置**:涵盖 9 个探测器:Git、SSH、npm、环境变量、Shell 历史、云凭证(AWS/GCP/Azure)、JetBrains IDE、GitHub CLI 和 AI CLI 工具。
* **密钥位置(仅元数据)**:由 8 个密钥检测器检测配置文件、环境变量和历史记录中是否存在 token、密钥和凭证——**绝不包含密钥值**。
有关每个探测器和检测器的详细文档,请参阅 [Bagel 文档站点](https://boostsecurityio.github.io/bagel/)。
## 隐私与安全设计
* **绝无负载。** Bagel 仅记录元数据(路径、所有者、权限、时间戳、配置标志、密钥类型/长度/过期时间)。输出或磁盘中绝不包含密钥值。
* **本地优先。** 报告默认以 JSON 格式打印到 stdout。
* **极低侵入性。** 只读操作;无进程注入;无网络扫描器。
* **透明。** 每个探测器都有文档记录,并可通过配置进行开关。
## 为什么要运行它?
现代供应链风险通常落在开发者终端(恶意包、配置错误的凭证、薄弱的密钥管理)。Bagel 标准化了可见性,以便安全团队可以:
* 发现高信号配置错误(例如:`http.sslVerify=false`、`ForwardAgent yes`、明文凭证文件、未加密的 SSH 密钥)。
* 检测 Shell 历史、`.env` 文件和配置文件中泄露的密钥。
* 使用 `--strict` 在 CI 中强制执行基线态势检查。
## 风险检查(示例)
* **Git**:`credential.helper=store`、`http.sslVerify=false`、使用非标准二进制文件的自定义 `core.sshCommand`、危险协议、fsck 被禁用。
* **npm**:`.npmrc` 中的 token、`strict-ssl=false`、HTTP(非 HTTPS)registry。
* **SSH**:无 passphrase 的密钥、`ForwardAgent yes`、`StrictHostKeyChecking=no`、宽松的文件权限。
* **环境与历史**:嵌入在环境变量、`.env` 文件或 Shell 命令历史中的密钥。
* **Cloud**:配置文件中的 AWS 凭证、GCP API 密钥、Azure 存储密钥。
## 安装
### 预构建二进制文件
从 [GitHub Releases](https://github.com/boostsecurityio/bagel/releases) 下载最新版本。
**macOS:**
```
# 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:**
```
brew tap boostsecurityio/tap
brew install bagel
```
**Linux:**
```
# 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:**
从 [releases 页面](https://github.com/boostsecurityio/bagel/releases) 下载 `bagel_Windows_x86_64.zip`,解压并将其添加到您的 PATH。
```
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 "."
```
### 从源码构建
需要 Go 1.25 或更高版本。
```
git clone https://github.com/boostsecurityio/bagel.git
cd bagel
go build -o bagel ./cmd/bagel
```
### 验证安装
```
bagel version
```
## 用法
```
bagel scan
```
这将扫描您的工作站并将结果以 JSON 格式输出到 stdout。
### 常用标志
| 标志 | 描述 |
|------|-------------|
| `--format`, `-f` | 输出格式:`json`(默认),`table` |
| `--output`, `-o` | 将输出写入文件而不是 stdout |
| `--strict` | 如果检测到任何发现,则以代码 2 退出 |
| `--no-cache` | 绕过文件索引缓存并强制重建 |
| `--no-progress` | 禁用进度条 |
| `--verbose`, `-v` | 启用详细(调试)日志记录 |
| `--config` | 配置文件的路径 |
### 示例
```
# 保存报告到文件
bagel scan -o report.json
# 表格输出以便快速查看
bagel scan -f table
# CI gate:如果存在发现则使构建失败
bagel scan --strict
# 调试特定扫描
bagel scan --verbose --no-progress
```
## 配置
Bagel 使用 YAML 配置文件。它会按以下顺序(从先到后)在以下位置查找 `bagel.yaml`:
1. 使用 `--config` 指定的路径
2. 当前目录(`./bagel.yaml`)
3. 平台配置目录(Unix 上为 `~/.config/bagel/bagel.yaml`,Windows 上为 `%APPDATA%\bagel\bagel.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_cli:
enabled: true
privacy:
redact_paths: []
exclude_env_prefixes: []
output:
include_file_hashes: false
include_file_content: false
```
默认情况下所有探测器均已启用。要禁用探测器,请设置 `enabled: false`。
## 输出模式(节选)
```
{
"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"
}
]
}
```
## 架构
* **探测器**:小型的、封闭的模块,用于扫描系统的特定区域。
* **检测器**:探测器使用的可复用密钥检测模式。
* **收集器**:通过超时和资源上限来编排探测器。
* **报告器**:渲染 JSON 或表格输出;为 CI 发出退出代码。
每个探测器都声明其范围(用户/系统)、触及的路径、读取的环境变量以及它可以发出的风险规则。
### 当前列出探测器
| 探测器 | 描述 | 检查内容 |
|-------|-------------|----------------|
| `git` | Git 配置安全 | SSL 验证已禁用,SSH 配置问题(StrictHostKeyChecking、UserKnownHostsFile),明文凭证实存储(`credential.helper=store`),危险协议(ext、fd、file),fsck 已禁用,代理设置,自定义钩子路径 |
| `ssh` | SSH 配置和密钥安全 | `StrictHostKeyChecking=no`,`UserKnownHostsFile=/dev/null`,`ForwardAgent=yes`,私钥文件权限,未加密的私钥 |
| `npm` | NPM/Yarn 配置 | `.npmrc` 和 `.yarnrc` 文件:`strict-ssl=false`,HTTP(非 HTTPS)registry,`always-auth` 设置 |
| `env` | 环境变量和点文件 | 环境变量,Shell 配置文件(`.bashrc`、`.zshrc`),用于嵌入密钥的 `.env` 文件 |
| `shell_history` | Shell 历史文件 | `.bash_history`、`.zsh_history` 中命令历史里的密钥 |
| `cloud` | 云服务商凭证 | AWS(`~/.aws/config`、`~/.aws/credentials`),GCP(`~/.config/gcloud/`),Azure 配置文件 |
| `jetbrains` | JetBrains IDE 配置 | JetBrains IDE 工作区文件和配置中嵌入的密钥 |
| `gh` | GitHub CLI | GitHub CLI 身份验证 token 和配置 |
| `ai_cli` | AI CLI 工具 | Gemini、Codex、Claude 和 OpenCode 的凭证文件和聊天日志 |
### 当前检测器
| 检测器 | 描述 | 检测模式 |
|----------|-------------|-------------------|
| `github-token` | GitHub 身份验证 token | 经典 PAT(`ghp_`),细粒度 PAT(`github_pat_`),OAuth(`gho_`),App User-to-Server(`ghu_`),App Server-to-Server(`ghs_`),Refresh Token(`ghr_`) |
| `npm-token` | NPM 身份验证 token | NPM auth token(`npm_*`) |
| `ai-service` | AI 服务 API 密钥 | OpenAI(`sk-`),Anthropic(`sk-ant-api03-`、`sk-ant-admin01-`),Hugging Face(`hf_`、`api_org_`) |
| `http-authentication` | HTTP 认证凭证 | Bearer token,Basic Auth 头,API key 头(`X-API-Key` 等),URL 中的 Basic Auth(`http://user:pass@host`) |
| `ssh-private-key` | SSH 私钥 | RSA、DSA、EC、OPENSSH、PKCS8 密钥;检测已加密与未加密 |
| `cloud-credentials` | 云服务商凭证 | AWS Access Key ID(`AKIA*`、`ASIA*` 等),GCP API Key(`AIza*`),Azure 存储账户密钥 |
| `generic-api-key` | 通用密钥 | 匹配常见密钥模式的高熵字符串(使用香农熵分析) |
| `jwt` | JSON Web Token | JWT token(`eyJ` 前缀且具有标准 JWT 结构) |
## 平台支持
| 操作系统 | 支持 |
|----|---------|
| macOS(Intel 和 Apple Silicon) | 完全支持 |
| Linux(x86_64 和 ARM64) | 完全支持 |
| Windows(x86_64) | 完全支持,具有平台特定的文件路径和 PowerShell 历史 |
所有探测器均可跨平台工作,并针对每个操作系统进行适当的路径处理。
## Scrub 命令
`bagel scrub` 从 AI CLI 会话日志和 Shell 历史文件中移除凭证,将其替换为 `[REDACTED-]` 标记,同时保留对话上下文。
```
# 扫描并交互式确认(默认)
bagel scrub
# 跳过提示,立即应用
bagel scrub --yes
# 仅扫描,不做修改
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
```
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--yes` / `-y` | `false` | 跳过确认提示并应用更改 |
| `--dry-run` | `false` | 仅扫描并报告,不修改文件 |
| `--grace-minutes` | `60` | 跳过在此分钟数内修改过的文件 |
| `--file` | | 清理单个文件而不是所有符合条件的文件 |
**目标:**
- `~/.claude/projects/**/*.jsonl` -- Claude Code 会话日志
- `~/.claude/projects/**/*.txt` -- Claude Code 工具结果
- `~/.codex/sessions/**/*.jsonl` -- Codex CLI 会话日志
- `~/.gemini/tmp/*/chats/*.json` -- Gemini CLI 聊天日志
- `~/.local/share/opencode/**/*.json` -- OpenCode 会话日志
- `~/.bash_history` -- Bash shell 历史
- `~/.zsh_history` -- Zsh shell 历史
- `~/.sh_history` -- 通用 shell 历史
- `~/.local/share/fish/fish_history` -- Fish shell 历史
**推荐工作流:**
1. `bagel scan -f table` -- 评估您的暴露面
2. `bagel scrub --yes` -- 清理
3. `bagel scan -f table` -- 验证减少情况
4. 轮换发现的任何凭证
## 集成
* **CI**:在您的流水线中运行 `bagel scan --strict`,以便在检测到发现时让构建失败。
## 退出代码
* `0` – 成功,未检测到发现(或未设置 `--strict`)
* `1` – 运行时错误
* `2` – 检测到发现(使用 `--strict` 时)
## 常见问题
**它会读取我的密钥吗?** 不会。它仅收集元数据和安全相关标志。
**它会制造噪音吗?** 探测器是只读的、批处理的,并且有时间限制,以保持在典型的开发机器上将扫描控制在一分钟内。
标签:AI工具安全, EVTX分析, GitHub CLI, JetBrains IDE, SamuraiWTF, SSH安全, StruQ, 云凭证检测, 历史记录分析, 安全助手, 开发者工作站, 数据防泄露, 文档结构分析, 日志审计, 本地安全, 汇编生成, 环境变量扫描, 秘密检测, 跨平台CLI, 风险发现