Files
zclaw_openfang/wiki/security.md
iven ed77095a37
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
docs(wiki): 系统性更新 — L0速览+L1模块标准化+L2功能链路映射(33条)
三层架构增强:
- L0 index.md: 用户功能清单+跨模块数据流全景图+导航树增强 (92→143行)
- L1 8个模块页标准化: 功能清单/API接口/测试链路/已知问题
  routing(252→326) chat(101→157) saas(153→230) memory(182→333)
  butler(137→179) middleware(121→159) hands-skills(218→257) pipeline(111→156)
- L1 新增2页: security.md(157行) data-model.md(180行)
- L2 feature-map.md: 33条端到端功能链路映射(408行)

维护机制: CLAUDE.md §8.3 wiki触发规则 5→9条
设计文档: docs/superpowers/specs/2026-04-21-wiki-systematic-overhaul-design.md
2026-04-21 23:48:19 +08:00

158 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 安全体系
updated: 2026-04-21
status: active
tags: [module, security, auth, encryption]
---
# 安全体系
> 从 [[index]] 导航。关联模块: [[saas]] [[routing]] [[middleware]]
## 设计思想
**核心原则: 多层防御,深度安全。**
1. **认证层** — JWT + Cookie + TOTP 2FA + 账户锁定
2. **传输层** — CORS 白名单 + Cookie Secure + HTTPS (反向代理)
3. **存储层** — Argon2id 密码 + AES-256-GCM 加密 + OS Keyring
4. **运行时层** — 限流 + 配额 + CSP + Guardrail 中间件
完整审计报告: `docs/features/SECURITY_PENETRATION_TEST_V1.md`
## 功能清单
| 功能 | 描述 | 入口文件 | 状态 |
|------|------|----------|------|
| JWT 认证 | 签发/验证/刷新/失效 | auth/handlers.rs | ✅ |
| Cookie 双通道 | Tauri keyring + 浏览器 HttpOnly | auth/handlers.rs | ✅ |
| TOTP 2FA | 设置/验证/禁用 | auth/totp.rs | ✅ |
| 密码安全 | Argon2id + OsRng 盐 + pwv 失效 | auth/handlers.rs | ✅ |
| Token 池加密 | AES-256-GCM + 随机 Nonce | relay/key_pool.rs | ✅ |
| OS Keyring | Win DPAPI/macOS Keychain/Linux Secret | secure_storage.rs | ✅ |
| 本地记忆加密 | AES-256-GCM (可选) | memory/crypto.rs | ✅ |
| 账户锁定 | 5 次失败锁 15 分钟 | auth/handlers.rs | ✅ |
| 限流 | IP 级 + 账户级滑动窗口 | middleware.rs | ✅ |
| CORS 白名单 | 生产缺失拒绝启动 | main.rs CorsLayer | ✅ |
| CSP | Tauri 移除 unsafe-inline | desktop/src-tauri/ | ✅ |
| Admin 权限 | admin_guard + RBAC | middleware.rs | ✅ |
## 代码逻辑
### 认证流程
```
用户登录 (POST /api/v1/auth/login)
→ Argon2id + OsRng 验证密码
→ 账户锁定检查 (5 次失败 → 15 分钟锁定)
→ 签发 JWT (Claims: user_id, role, pwv)
→ set_auth_cookies():
zclaw_access_token (path:/api, 2h TTL, HttpOnly)
zclaw_refresh_token (path:/api/v1/auth, 7d TTL, HttpOnly)
Secure: dev=false, prod=true | SameSite=Strict
前端存储:
→ Tauri: OS keyring → saasStore.token
→ 浏览器: HttpOnly Cookie (JS 不可读)
→ localStorage: 仅 saasUrl + account 非敏感信息
```
### JWT Password Version 失效机制
```
JWT Claims 含 pwv (password_version) 字段
→ 每次验证 JWT 时比对 Claims.pwv vs DB.pwv
→ 修改密码 → DB.pwv 递增 → 所有旧 JWT 自动失效
```
### Token 池安全
```
Provider Key 存储: AES-256-GCM + 随机 Nonce 加密
→ 解密失败: warn + skip 到下一个 Key (不阻塞 relay)
→ 启动时: heal_provider_keys() 自动重新加密有效 Key
→ TOTP 加密密钥: 生产环境强制独立 ZCLAW_TOTP_ENCRYPTION_KEY
```
### SaaS HTTP 中间件栈 (10 层)
| # | 中间件 | 路由组 | 功能 |
|---|--------|--------|------|
| 1 | public_rate_limit | Public | IP 限流: login 5/min, register 3/hour |
| 2 | auth_middleware | Protected+Relay | JWT/Cookie/API Token 身份验证 |
| 3 | rate_limit_middleware | Protected+Relay | 账户级请求频率限制 |
| 4 | quota_check_middleware | Relay | 月度配额检查 (relay_requests + input_tokens) |
| 5 | request_id_middleware | All | UUID 请求追踪 |
| 6 | api_version_middleware | All | API 版本头 |
| 7 | TimeoutLayer (15s) | Protected | 非流式请求超时 |
| 8 | admin_guard | Admin 子路由 | admin 权限验证 |
| G1 | TraceLayer | All | HTTP 请求追踪 |
| G2 | CorsLayer | All | CORS 白名单 (生产缺失拒绝启动) |
## API 接口
### Auth 公开路由
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/v1/auth/register` | 注册 (邮箱 RFC 5322 + 254 字符限制) |
| POST | `/api/v1/auth/login` | 登录 (5 次/分钟 IP 限流) |
| POST | `/api/v1/auth/refresh` | 刷新 Token (单次使用,旧 token 撤销到 DB) |
| POST | `/api/v1/auth/logout` | 登出 |
### Auth 受保护路由
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/auth/me` | 当前用户信息 |
| PUT | `/api/v1/auth/password` | 修改密码 (触发 pwv 失效) |
| POST | `/api/v1/auth/totp/setup` | TOTP 设置 (生成 QR) |
| POST | `/api/v1/auth/totp/verify` | TOTP 验证激活 |
| POST | `/api/v1/auth/totp/disable` | TOTP 禁用 (需密码) |
### Tauri 安全命令
| 命令 | 说明 |
|------|------|
| `secure_store_set` | OS Keyring 存储 |
| `secure_store_get` | OS Keyring 读取 |
| `secure_store_delete` | OS Keyring 删除 |
| `secure_store_is_available` | Keyring 可用性检测 |
## 测试链路
| 功能 | 测试文件 | 覆盖状态 |
|------|---------|---------|
| 认证流程 | `crates/zclaw-saas/tests/auth_test.rs` | ✅ |
| 认证安全边界 | `crates/zclaw-saas/tests/auth_security_test.rs` | ✅ |
| 账户安全 | `crates/zclaw-saas/tests/account_security_test.rs` | ✅ |
| 权限矩阵 | `crates/zclaw-saas/tests/permission_matrix_test.rs` | ✅ |
| TOTP | `crates/zclaw-saas/src/auth/totp.rs` inline | ✅ |
| 本地加密 | `desktop/src-tauri/src/memory/crypto.rs` inline | ✅ |
## 关联模块
- [[saas]] — 安全体系运行在 SaaS 后端
- [[routing]] — SaaS JWT 用于 relay 认证
- [[middleware]] — Guardrail + LoopGuard + SubagentLimit 运行时安全
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-saas/src/auth/handlers.rs` | 认证端点实现 |
| `crates/zclaw-saas/src/auth/totp.rs` | TOTP 2FA 实现 |
| `crates/zclaw-saas/src/middleware.rs` | HTTP 中间件栈 |
| `crates/zclaw-saas/src/relay/key_pool.rs` | Token Pool + Key 加密 |
| `desktop/src-tauri/src/secure_storage.rs` | OS Keyring 接口 |
| `desktop/src-tauri/src/memory/crypto.rs` | 本地 AES-256-GCM |
| `docs/features/SECURITY_PENETRATION_TEST_V1.md` | 安全审计报告 |
## 已知问题
-**JWT 签名密钥 fallback**`#[cfg(debug_assertions)]` 保护release 拒绝启动
-**TOTP 加密密钥解耦** — 生产环境强制独立 `ZCLAW_TOTP_ENCRYPTION_KEY`
-**Cookie Secure 标志** — dev=false, prod=true
-**CORS 白名单** — 生产缺失拒绝启动
-**Admin 404→403** — admin_guard_middleware 已修复