title, updated, status, tags
| title |
updated |
status |
tags |
| 安全体系 |
2026-04-22 |
active |
| module |
| security |
| auth |
| encryption |
|
安全体系
从 index 导航。关联模块: saas routing middleware
设计决策
核心原则: 多层防御,深度安全。
| 决策 |
为什么 |
| JWT + HttpOnly Cookie 双通道 |
Tauri 桌面端用 OS keyring 存 JWT,浏览器用 HttpOnly Cookie 防 XSS 窃取,双环境统一认证 |
| password_version (pwv) 失效 |
修改密码后自动使所有已签发 JWT 失效,无需 token 黑名单,O(1) 验证 |
| TOTP AES-256-GCM 加密 |
TOTP 共享密钥不能明文存储,随机 Nonce 防重放,生产环境强制独立密钥 |
| IP 级限流 + 持久化 |
防暴力破解(login 5/min)、防刷注册(3/hour),持久化到 PostgreSQL 避免重启丢失 |
| CORS 白名单强制 |
生产环境 cors_origins 缺失直接拒绝启动,不允许 * 通配 |
完整审计报告: docs/features/SECURITY_PENETRATION_TEST_V1.md
关键文件 + 数据流
核心文件
| 文件 |
职责 |
crates/zclaw-saas/src/auth/handlers.rs |
认证端点: 登录/注册/刷新/TOTP/密码修改 |
crates/zclaw-saas/src/auth/totp.rs |
TOTP 2FA: QR 生成 + 验证 + AES-256-GCM 加密 |
crates/zclaw-saas/src/middleware.rs |
HTTP 中间件栈 (10 层): 认证/限流/配额/CORS |
crates/zclaw-saas/src/relay/key_pool.rs |
Token Pool: Key 加密存储 + RPM/TPM 轮换 |
desktop/src-tauri/src/secure_storage.rs |
OS Keyring: Win DPAPI / macOS Keychain / Linux Secret |
desktop/src-tauri/src/memory/crypto.rs |
本地记忆加密: AES-256-GCM (可选) |
认证数据流
集成契约
| 方向 |
接口 |
说明 |
| Provides --> saas |
auth_middleware, JWT validation, rate limiting |
每个 API 请求经过认证层 |
| Provides --> desktop |
secure_storage, crypto_utils |
配置/凭据安全存储 |
| Provides --> admin |
admin_guard_middleware |
Admin 路由权限验证 |
Auth API 接口
公开路由:
| 方法 |
路径 |
说明 |
| POST |
/api/v1/auth/register |
注册 (邮箱 RFC 5322 + 254 字符) |
| POST |
/api/v1/auth/login |
登录 (5 次/分钟 IP 限流) |
| POST |
/api/v1/auth/refresh |
Token 刷新 (单次使用, 旧 token 撤销) |
| POST |
/api/v1/auth/logout |
登出 |
受保护路由:
| 方法 |
路径 |
说明 |
| 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 可用性检测 |
代码逻辑
JWT Password Version 失效机制
密码存储: Argon2id + OsRng
TOTP / API Key 加密: AES-256-GCM
Token 刷新轮换
限流规则
| 端点 |
限制 |
持久化 |
/api/auth/login |
5 次/分钟/IP |
PostgreSQL |
/api/auth/register |
3 次/小时/IP |
PostgreSQL |
| 公共端点 |
20 次/分钟/IP |
内存 |
SaaS HTTP 中间件栈 (10 层)
| # |
中间件 |
路由组 |
功能 |
| 1 |
public_rate_limit |
Public |
IP 限流 |
| 2 |
auth_middleware |
Protected+Relay |
JWT/Cookie/API Token 身份验证 |
| 3 |
rate_limit_middleware |
Protected+Relay |
账户级频率限制 |
| 4 |
quota_check_middleware |
Relay |
月度配额检查 |
| 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 白名单 |
活跃问题 + 陷阱
| 问题 |
级别 |
说明 |
| CSP 已加固 |
Done |
Tauri 移除 unsafe-inline script,connect-src 限制 http://localhost:* + https://* |
| TLS 依赖反向代理 |
长期 |
Axum 不负责 TLS,nginx/caddy 提供 HTTPS 终止 |
| Cookie Secure 开发环境 false |
设计意图 |
开发环境 HTTP 无 Secure,生产必须 true |
陷阱:
- JWT 签名密钥:
#[cfg(debug_assertions)] 有 fallback,release 模式直接 bail 拒绝启动
- TOTP 加密密钥: 生产必须独立设置
ZCLAW_TOTP_ENCRYPTION_KEY,不从 JWT 密钥派生
- CORS 白名单: 生产缺失拒绝启动,不允许通配符
- Refresh Token: 单次使用,logout 时撤销到 DB,rotation 校验已撤销的旧 token
变更日志
| 日期 |
变更 |
提交 |
| 2026-04-21 |
移除数据脱敏中间件 (稳定化约束) |
fa5ab4e |
| 2026-04-17 |
E2E 测试安全链路验证通过 |
— |
| 2026-04-16 |
Agent 隔离修复 + Admin 权限校验 |
— |
| 2026-04-13 |
安全渗透测试 V1: 15 项修复 |
— |
| 2026-04-09 |
CSP 加固 + JWT pwv + 账户锁定 + TOTP 解耦 |
— |
测试覆盖
| 功能 |
测试文件 |
| 认证流程 |
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 tests |
| 本地加密 |
desktop/src-tauri/src/memory/crypto.rs inline tests |