> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeus.agentspro.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 认证鉴权

> Zeus 服务间 JWT 认证

# JWT 服务认证

## 概述

Zeus 采用**双层认证架构**：

* **用户认证**: Better Auth (Session-based) — 详见 [Web 认证](/en/web/Auth)
* **服务认证**: JWT + JWKS (Stateless)

## 认证架构

```mermaid theme={null}
sequenceDiagram
    participant User as 用户（浏览器）
    participant Web as Web - Next.js
    participant Backend as ai-backend - Python

    User->>Web: ① 邮箱密码 / OAuth 登录
    Web->>Web: Better Auth 验证身份，创建 Session
    User->>Web: ② 发起 AI 请求
    Web->>Web: 调用 /api/auth/token 获取 JWT
    Web->>Backend: ③ HTTP + Authorization: Bearer JWT
    Backend->>Backend: JWKS 验证 Token 签名，提取用户信息
    Backend-->>User: 响应
```

## 为什么需要双层认证

**只有用户认证的问题**：

```
用户 → Web → ai-backend
              ↑
              任何人都可以直接调用！
```

**用户认证 + 服务认证**：

```
用户 → Web (用户认证) → ai-backend (服务认证)
                         ↑
                         只接受来自 Web 的请求
```

## JWT 工作原理

### Token 获取流程

1. 用户登录 → Better Auth 创建 Session
2. 调用 `/api/auth/token` → Better Auth 签发 JWT
3. Web API 使用 JWT → 调用 ai-backend
4. ai-backend 验证 JWT → 通过 JWKS 验证签名

### Token 结构

```
eyJhbGciOiJFZERTQSJ9.eyJ1c2VySWQiOiJ1c2VyX2FiYzEyMyJ9.signature
│                    │                                    │
│                    │                                    └─ 签名（EdDSA）
│                    └─ Payload（用户数据）
└─ Header（算法信息）
```

### JWKS 验证流程

1. **提取 Token**：从 `Authorization: Bearer <token>` 头部提取
2. **获取 JWKS**：从 `/api/auth/jwks` 获取公钥（带缓存）
3. **查找密钥**：根据 Token Header 中的 `kid` 查找对应公钥
4. **验证签名**：使用公钥验证 Token 未被篡改
5. **检查过期**：验证 Token 未过期
6. **返回用户信息**：提取 `userId`, `email`, `name`

## 受保护的 API

### 需要 JWT 认证

| 模块      | 接口                  | 说明        |
| ------- | ------------------- | --------- |
| Chat    | `/api/agent/invoke` | Agent 模式  |
| Sandbox | `/api/sandbox/*`    | 沙盒操作      |
| MCP     | `/api/mcp/*`        | MCP 管理    |
| Skills  | `/api/skills/*`     | Skills 管理 |

### 不需要 JWT 认证

| 接口        | 说明   |
| --------- | ---- |
| `/`       | 根路径  |
| `/health` | 健康检查 |

## 安全最佳实践

### 1. 非对称加密

使用 **EdDSA (Ed25519)**：

* 后端无需共享密钥
* 私钥只在 Web 端
* 支持密钥轮换

### 2. 密钥轮换

* 轮换周期：30 天
* 旧密钥保留：30 天

### 3. Token 有效期 (双 Token 机制)

| Token 类型              | 有效期  | 用途                      |
| --------------------- | ---- | ----------------------- |
| accessToken (JWT)     | 1 小时 | 每次 API 调用的 Bearer Token |
| refreshToken (opaque) | 30 天 | 用于静默换取新的 accessToken    |

Desktop/iOS/Android 原生客户端使用双 Token 机制：

* accessToken 过期前 5 分钟自动刷新
* 刷新失败（refreshToken 过期）自动退出登录
* refreshToken 以 SHA-256 哈希存储在数据库中

### Token 刷新流程

```mermaid theme={null}
sequenceDiagram
    participant Client as Desktop / iOS / Android
    participant Web as Next.js (Web API)
    participant DB as PostgreSQL

    Client->>Client: 检查 accessToken exp < 5min
    Client->>Web: POST /api/auth/refresh {refreshToken}
    Web->>Web: SHA-256(refreshToken) → tokenHash
    Web->>DB: 查找 tokenHash + 验证未过期
    DB-->>Web: 用户信息
    Web->>Web: JWKS 私钥签发新 JWT
    Web-->>Client: {accessToken, expiresIn: 3600}
    Client->>Client: 更新本地存储，继续调用
```

### Refresh Token 安全

* **哈希存储**：数据库只存储 SHA-256 哈希，即使泄漏也无法直接使用
* **级联删除**：用户删除时自动清理所有 refreshToken 记录
* **单独作废**：可按用户 ID 批量吊销所有 refreshToken

### 4. JWKS 缓存

* 缓存时间：1 小时
* 密钥轮换时自动刷新

### 5. 传输安全

* 生产环境必须使用 HTTPS
* Token 只在 HTTP Header 中传输
* 不要在 URL 中传递 Token
