clawshell/clawshell
GitHub: clawshell/clawshell
ClawShell 是专为 OpenClaw/Hermes Agent 设计的运行时安全层,用于安全映射 API 密钥并扫描敏感数据以防止泄露。
Stars: 280 | Forks: 23
# ClawShell 🛡️

[](LICENSE)
[](https://github.com/clawshell/clawshell/actions)
[](https://www.npmjs.com/package/@clawshell/clawshell)
[](https://crates.io/crates/clawshell)
## 📖 简介
**ClawShell** 是 **OpenClaw/Hermes Agent** 生态系统中具有安全特权的进程。它位于 OpenClaw/Hermes Agent 和上游 LLM API 提供商(OpenAI、Anthropic、OpenRouter)之间,执行虚拟到真实 API 密钥的映射,并对请求和响应体进行 DLP(数据防泄漏)扫描。它还可以暴露一个邮件读取端点,并提供发件人白名单/黑名单过滤功能。
OpenClaw/Hermes Agent 从不持有真实的 API 密钥,只持有虚拟密钥,ClawShell 会在转发请求到上游之前将其替换为真实密钥。真实密钥存储在受保护的特权配置目录(`/etc/clawshell`)中,该目录受 Unix 文件系统权限保护。
## 主要特性
### 1. API 令牌安全绑定
ClawShell 将虚拟 API 密钥映射到真实的提供商密钥,从而使 OpenClaw/Hermes Agent 永远无法直接访问真实凭据。
- **密钥隔离**:真实的 API 密钥存储在 `/etc/clawshell/clawshell.toml` 中,仅对 `clawshell` 系统用户可读。OpenClaw/Hermes Agent 仅持有虚拟密钥。
- **多提供商支持**:将密钥映射到 OpenAI 或 Anthropic,并注入正确的认证头格式(OpenAI 使用 `Authorization: Bearer`,Anthropic 使用 `x-api-key`)。
### 2. PII 安全网 (DLP)
ClawShell 使用可配置的正则表达式模式扫描 HTTP 请求和响应体中的敏感数据。
- **请求扫描**:检测出站请求中的 PII(社会安全号码、信用卡号、电子邮件等)。模式可配置为阻止请求或在转发前编辑匹配的文本。
- **响应扫描**:可选择扫描上游响应,并在返回给 OpenClaw/Hermes Agent 前编辑检测到的 PII。流式 (SSE) 响应会直接传递而不进行扫描。
- **自定义模式**:在 TOML 配置中使用正则表达式定义敏感数据模式,每个模式都有 `block`(阻止)或 `redact`(编辑)动作。
### 3. 敏感邮件隔离
ClawShell 支持基于发件人的邮件过滤,因此每个虚拟密钥只能根据发件人规则查看邮箱内容。
- **发件人过滤**:按发件人过滤邮件。
- **密钥隔离**:IMAP 凭据存储在 `/etc/clawshell/clawshell.toml` 中,仅对 `clawshell` 系统用户可读。OpenClaw/Hermes Agent 仅持有虚拟密钥。
- **提供商支持**:内置 Gmail 和 Outlook 预设,其他提供商可手动设置 IMAP。
### 4. OAuth 认证 (Codex / ChatGPT)
ClawShell 支持基于 OAuth 的认证,作为静态 API 密钥的替代方案。
- **设备码流程**:通过一次性代码登录——服务器上无需浏览器。设置向导会打印一个 URL 和代码;从任何设备进行授权。
- **自动令牌刷新**:访问令牌在过期前被透明刷新。
- **请求转换**:使用 Codex OAuth 时,自动将 OpenAI Chat Completions API 请求转换为 ChatGPT Responses API 格式。
### 5. 运行时统计
ClawShell 在 `GET /admin/stats` 暴露运行计数器,以便操作员可以审计代理自启动以来以及重启期间的活动。
- **统计内容**:受保护的请求总数、上游 `prompt_tokens` / `completion_tokens` / `total_tokens` 总数(从非流式 JSON 响应中解析——SSE 流不计数)、被发件人策略隐藏的邮件数量,以及按地址分类的已过滤发件人明细。
- **仅本地访问**:该端点无需虚拟密钥即可访问,但只能从 `127.0.0.1` / `::1` 对等方访问;非本地客户端会收到 `403`。
- **持久化**:计数器每 30 秒以及在正常关闭时刷新到磁盘。位置是一个必需的配置字段——在 `clawshell.toml` 中设置 `[stats] persist_path = "..."`(在强化的 systemd 单元下通常是 `/var/lib/clawshell/stats.json`,因为 `/etc/clawshell` 在那里是只读的)。
- **有界**:过滤地址映射上限为 10,000 个唯一条目;更多唯一地址会在一个 `` 桶中聚合,以确保内存使用有界。
### 6. 无缝集成
- **即插即用的边车容器**:`clawshell onboard` 向导每次运行时精确配置一个下游 LLM 客户端——OpenClaw 或 [Hermes Agent](https://github.com/NousResearch/hermes-agent)——将所有请求通过 ClawShell 的代理路由。参见 [代理目标(选择一个)](#agent-target-pick-one)。
- **无外部依赖**:使用 Unix 文件系统权限保护秘密。不需要 IdP、Vault 或外部密钥管理服务。
### 7. 超轻量级与可扩展性
- 运行内存占用低于 10MB。
- 使用 Rust 编写,基于 Tokio 异步运行时。
## 架构
```
║ security boundary (Unix File System Permissions)
║
║ ┌───────────────────────────┐
║ │ /etc/clawshell │
║ │ ┄ real API keys │
║ │ ┄ DLP patterns │
║ │ ┄ email sender rules │
║ │ ┄ IMAP account creds │
║ └──────────┬────────────────┘
║ reads │
║ ┌──────────┴────────────────┐
┌──────────────┐ REQUEST ║ │ │ REQUEST ┌────────────┐
│ ├──(virtual───╫─►│ ClawShell ├──-(real key,───►│ │
│ OpenClaw or │ key) ║ │ │ PII redacted) │ OpenAI / │
│ Hermes Agent │ ║ │ DLP scan │ │ Anthropic/ │
│ holds only │ RESPONSE ║ │ real-key mapping │ RESPONSE │ OpenRouter │
│ virtual keys │◄────────────║◄─┤ email sender filtering │◄────────────────┤ │
│ │ ║ │ │ └────────────┘
│ │ EMAIL GET ║ │ │ IMAP fetch ┌────────────┐
│ ├───(virtual──║ | |───(real key)───►| |
│ │ key) ║ │ │ │ IMAP │
│ │ ║ │ │ | Provider │
│ │ ║ │ │ RESPONSE │ Gmail / │
│ │ filtered ║ │ │◄────────────────│ Outlook / │
│ │◄────────────║◄─| | │ custom │
└──────────────┘ ║ | | └────────────┘
║ └───────────────────────────┘
```
OpenClaw/Hermes Agent 仅持有虚拟密钥,无法访问存储在特权配置中的真实 API 密钥。
ClawShell 将虚拟密钥替换为真实密钥,并在将请求转发到上游之前扫描 PII。
ClawShell 还在返回邮件数据前强制执行基于发件人的过滤。
## 安装
### Cargo
```
cargo install clawshell --locked
# 需要权限才能设置安全边界
sudo clawshell onboard
```
### NPM
```
npm install -g @clawshell/clawshell
# 需要权限才能设置安全边界
sudo clawshell onboard
```
### 从源代码构建
```
RUSTFLAGS="--remap-path-prefix=$(pwd)=. --remap-path-prefix=$HOME=/" cargo build --release
ls -al target/release/clawshell
```
#### 在 Linux/arm64 上交叉编译
```
wget https://musl.cc/x86_64-linux-musl-cross.tgz -O /tmp/musl-cross.tgz
tar -xzf /tmp/musl-cross.tgz -C /tmp
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER="/tmp/x86_64-linux-musl-cross/bin/x86_64-linux-musl-gcc" \
RUSTFLAGS="--remap-path-prefix=$(pwd)=. --remap-path-prefix=$HOME=/" \
cargo build --release --target x86_64-unknown-linux-musl
```
## 高级用法
### 初始设置
`onboard` 命令是一个交互式设置向导,必须使用 `sudo` 运行。它会:
1. 询问要通过 ClawShell 连接哪个下游代理——**OpenClaw** 或 **Hermes Agent**(每次运行只配置一个)。
2. 创建 `clawshell` 系统用户。
3. 创建并保护 `/etc/clawshell`(权限模式 700)和 `/var/log/clawshell`。
4. 引导你完成提供商选择、API 密钥输入和虚拟密钥生成。
5. 将 ClawShell 配置写入 `/etc/clawshell/clawshell.toml`。
6. 将选定的代理连接到 ClawShell(为 OpenClaw 打补丁 `~/.openclaw/openclaw.json`,或为 Hermes 运行 `hermes config set`)。
7. 启动 ClawShell 守护进程。
```
sudo clawshell onboard
```
### 更多命令
```
# 启动(默认以守护进程方式运行)
sudo clawshell start
# 前台启动
sudo clawshell start --foreground
# 使用自定义配置文件启动
sudo clawshell start -c /path/to/clawshell.toml
# 检查状态
clawshell status
# 查看日志
clawshell logs
clawshell logs --level error
clawshell logs --follow
# 重启 / 停止
sudo clawshell restart
sudo clawshell stop
# 将配置架构迁移到当前版本
sudo clawshell migrate-config
```
默认情况下,ClawShell 监听 `127.0.0.1:18790`。
你可以在运行时使用环境变量覆盖绑定地址:
```
CLAWSHELL_SERVER_HOST=0.0.0.0 CLAWSHELL_SERVER_PORT=17890 clawshell start --foreground
```
### 自定义配置
ClawShell 从 `/etc/clawshell/clawshell.toml` 读取其配置。你可以使用以下命令查看或编辑它:
```
sudo clawshell config # print current config
sudo clawshell config --edit # open in $EDITOR
```
一个最小配置如下所示:
```
version = "0.2.1"
log_level = "info"
[server]
host = "127.0.0.1"
port = 18790
[upstream]
openai_base_url = "https://api.openai.com"
anthropic_base_url = "https://api.anthropic.com"
# 虚拟到真实 API 密钥映射
[[keys]]
virtual_key = "vk-alice-001"
real_key = "sk-your-real-openai-key-here"
provider = "openai"
[[keys]]
virtual_key = "vk-claude-001"
real_key = "sk-ant-your-real-anthropic-key-here"
provider = "anthropic"
# 数据防泄漏 (DLP)
# action = "block" -> 以 400 拒绝请求
# action = "redact" -> 将匹配项替换为 [REDACTED:] 并转发
[dlp]
scan_responses = false
patterns = [
{ name = "ssn", regex = '\b\d{3}-\d{2}-\d{4}\b', action = "redact" },
{ name = "visa_card", regex = '\b4[0-9]{12}(?:[0-9]{3})?\b', action = "redact" },
{ name = "amex_card", regex = '\b3[47][0-9]{13}\b', action = "redact" },
]
# 电子邮件安全端点
[email]
enabled = true
mode = "allowlist"
allow_senders = ["alice@example.com", "@trusted.org"]
deny_senders = []
default_max_results = 50
[[email.accounts]]
virtual_key = "vk-email-001"
email = "bot@gmail.com"
app_password = "abcd efgh ijkl mnop"
imap_host = "imap.gmail.com"
imap_port = 993
# Outlook 预设示例:
# imap_host = "imap-mail.outlook.com"
```
### OAuth 认证 (Codex / ChatGPT)
你可以使用你的 ChatGPT / Codex 账户通过 OAuth 进行认证,而不是使用静态 API 密钥。
#### 通过 onboard 设置
在运行 `sudo clawshell onboard` 期间,选择 **"Codex / ChatGPT (OAuth)"** 作为提供商。向导将启动设备码流程:
1. 一个 URL 和一次性代码将打印到终端。
2. 在任何设备上打开该 URL 并输入代码。
3. 授权后,令牌会自动保存到 `/etc/clawshell/oauth/`。
服务器上不需要浏览器。
#### 手动配置
要在 `clawshell.toml` 中手动配置 OAuth:
```
# OAuth 支持的密钥 — 无需 real_key
[[keys]]
virtual_key = "vk-codex-001"
auth = "oauth"
oauth_provider = "codex"
provider = "openai"
# OAuth 提供程序定义
[[oauth_providers]]
provider = "codex"
# 可选覆盖项(默认适用于 ChatGPT):
# client_id = "app_EMoamEEZ73f0CkXaXp7hrann"
# auth_url = "https://auth.openai.com/authorize"
# token_url = "https://auth.openai.com/oauth/token"
```
ClawShell 会自动处理令牌刷新。使用 Codex OAuth 时,发送到 `/v1/chat/completions` 的请求会被转换为 ChatGPT Responses API 格式,并路由到 `chatgpt.com/backend-api/codex`。
如果 `start`、`restart`、`stop`、`config --edit`、`onboard` 或 `uninstall` 报告需要迁移,请运行:
```
sudo clawshell migrate-config --config /etc/clawshell/clawshell.toml
```
完整示例请参见 [`clawshell.example.toml`](clawshell.example.toml)。
### 代理目标(选择一个)
`sudo clawshell onboard` 从一项单一、必须的选择开始:
```
=== Agent Target ===
? Which downstream agent should ClawShell wire through?
> OpenClaw
Hermes Agent
```
每次 onboard 运行**仅配置一个**下游客户端。没有“也配置另一个”的路径——稍后切换意味着重新运行 `sudo clawshell onboard` 并选择另一个目标。提示没有默认的预选,因此你每次都需要明确选择。
#### OpenClaw 目标
当你选择 OpenClaw 时,向导会:
- 备份 `~/.openclaw/openclaw.json`(编号的 `.bak` 文件,权限模式 000)。
- 调用 `openclaw config set` 来修补三个路径:`env.CLAWSHELL_API_KEY`、`agents.defaults.models.clawshell/` 和 `models.providers.clawshell`。
- 当启用邮件集成时,将 `get-email-messages` 技能包写入 `/skills/`。
- 在最后询问是否运行 `openclaw models set clawshell` 和 `openclaw gateway restart`。
这是历史设置流程,不受目标选择重构的影响。
#### Hermes Agent 目标
当你选择 [Hermes Agent](https://github.com/NousResearch/hermes-agent) 时,向导会:
- 跳过所有 OpenClaw 步骤——**不会**触碰 `~/.openclaw/`。
- 当启用邮件集成时,将 `get-email-messages` 技能包写入 `~/.hermes/skills/`(属于调用用户,而不是 root)。Hermes 会从该目录自动发现技能。
- 调用 `hermes config set` 来写入:
| 键 | 值 |
|---|---|
| `model.provider` | `custom` |
| `model.base_url` | `http://:/v1` |
| `model.default` | 你在 onboard 期间选择的模型 ID |
| `model.api_key` | 你的 ClawShell **虚拟**密钥(永远不要用真实的上游密钥) |
`hermes` 二进制文件必须在你的 `PATH` 中。ClawShell 在调用它之前会放弃 root 权限,因此写入操作属于你的普通用户账户,而不是 root。
#### 手动配置 Hermes
如果你想跳过向导的 Hermes 集成,请从你的用户账户(而不是 root)运行等效命令:
```
hermes config set model.provider custom
hermes config set model.base_url http://127.0.0.1:18790/v1
hermes config set model.default
hermes config set model.api_key
```
然后使用 `hermes config show` 验证。
#### 撤销 Hermes 配置
Hermes 没有 `config unset` 子命令。要将 Hermes 从 ClawShell 分离,请将提供商设置回自动检测,Hermes 将根据其仍持有的凭据选择另一个上游:
```
hermes config set model.provider auto
```
### 卸载
```
sudo clawshell uninstall
```
## 许可证
本项目基于 [Apache License 2.0](LICENSE) 许可。
标签:API安全, API密钥隔离, DLP扫描, Email安全, GNU通用公共许可证, JSON输出, Node.js, PII保护, ProjectDiscovery, Python安全, Rust语言, Unix权限, 代码分析, 凭证管理, 可视化界面, 响应过滤, 安全中间件, 敏感数据检测, 数据保护, 白名单/黑名单, 系统权限管理, 网络安全, 虚拟密钥映射, 通知系统, 配置安全, 隐私保护, 隐私合规